让线程等待 Windows 表单响应?

发布于 2024-09-12 05:03:55 字数 735 浏览 4 评论 0原文

我有一个同时运行两个线程的 Windows 窗体应用程序,其中 UI 线程在任务栏中运行。 UI 线程实际上执行与其他进程完全独立的功能,但在新用户登录应用程序的情况下,我需要从非 UI 线程弹出一个设置窗口。

以下是我的 Program.cs 中的代码:

static void Main()
    {
        ThreadStart start = new ThreadStart(Waiting.wait);
        Thread waiting = new Thread(start);
        waiting.Start();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        Application.Run(TaskBarIcon.getInstance());
    }

目前,在 TaskBarIcon 完全实例化之前,必须在等待线程中完成一种配置方法的运行。这是通过来回传递锁来实现的。 我希望在处理配置方法时弹出此设置菜单,并让该方法等待完成,直到设置菜单运行完毕。但是,除非我直接从 Application.Run() 方法运行设置菜单,否则我什至无法使菜单正确显示。

我对 C# 很陌生......可以在 Java 中快速完成此操作,但 C# 似乎做事不同。

任何建议或解决方案将不胜感激!

坏熊猫

I have a windows forms application that runs two threads simultaneously, with the UI thread running in the task bar. The UI thread actually performs completely separate functionality from the other process, but in the case that a new user logs into the application, I need to pop up a setup window from the non-UI thread.

Here is the code from my Program.cs:

static void Main()
    {
        ThreadStart start = new ThreadStart(Waiting.wait);
        Thread waiting = new Thread(start);
        waiting.Start();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        Application.Run(TaskBarIcon.getInstance());
    }

Currently, before TaskBarIcon can fully instantiate, one configuration method must be finished running in the waiting thread. This is achieved by passing a lock back and forth.
I would like to have this set up menu pop up while the configuration method is processing, and have the method wait to complete until the setup menu is done running. However, unless I run the set up menu directly from the Application.Run() method, I cannot even get the menu to show up properly.

I'm very new to C#....would be able to do this quickly in Java, but C# seems to do things differently.

Any suggestions or solutions would be greatly appreciated!

badPanda

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花期渐远 2024-09-19 05:03:55

我怀疑发生的情况是设置菜单表单没有在工作线程上接收 Windows 消息,这就是它没有显示的原因。所有表单和控件都需要消息泵才能正常工作。启动消息泵有多种不同的方法,但最适合您的两种方法是:

  • Application.Run
  • Form.ShowDialog

如果您在设置菜单窗体上调用 ShowDialog ,那么它应该显示在工作线程。当然,调用会阻塞,直到表单关闭,这样就会阻止配置方法的其余部分执行,但话又说回来,这可能正是您想要的。

如果您希望主 UI 线程(调用 Application.Run 的线程)等待此配置方法完成,则使用 WaitHandle 在配置任务完成时发出信号。它可能如下所示。

static void Main() 
{ 
  var configured = new ManualResetEvent(false);
  var worker = new Thread(
    () =>
    {
       // Do some stuff here.

       CallYourConfigurationMethod();
       configured.Set() // Signal that configuration is complete.

       // Do some more stuff here.
    });
  worker.Start(); 
  configured.WaitOne();
  Application.EnableVisualStyles(); 
  Application.SetCompatibleTextRenderingDefault(true); 
  Application.Run(TaskBarIcon.getInstance()); 
} 

I suspect what it is happening is that the setup menu form is not receiving windows messages on the worker thread and that is why it is not showing up. All forms and controls need a message pump to work properly. There are various different ways of getting a message pump started, but the two most applicable to you are:

  • Application.Run
  • Form.ShowDialog

If you call ShowDialog on the setup menu form then it should show up on the worker thread. Of course the call blocks until the form is closed so that will prevent the remainder of the configuration method from executing, but then again that may be exactly what you want.

If you want the main UI thread (the one calling Application.Run) to wait until this configuration method is finished then use a WaitHandle to signal when the configuration task is complete. It might look like the following.

static void Main() 
{ 
  var configured = new ManualResetEvent(false);
  var worker = new Thread(
    () =>
    {
       // Do some stuff here.

       CallYourConfigurationMethod();
       configured.Set() // Signal that configuration is complete.

       // Do some more stuff here.
    });
  worker.Start(); 
  configured.WaitOne();
  Application.EnableVisualStyles(); 
  Application.SetCompatibleTextRenderingDefault(true); 
  Application.Run(TaskBarIcon.getInstance()); 
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文