【问题标题】:Handling Background Events on the Main Thread在主线程上处理后台事件
【发布时间】:2011-08-02 22:00:12
【问题描述】:

我创建了一个后台线程来做一些工作,最后我调用了一个方法ThreadDone(threadWorkResult) 来引发一个事件。目前,事件处理程序在同一个后台线程上运行,但我希望它在主 UI 线程(表单应用程序)上运行。我在网上搜索并找到了一些关于使用属性here 但想知道如何以编程方式执行此操作。有什么办法可以在处理程序本身之外完成吗?

我查看了 BackgroundWorker,但我必须同时创建多个线程,因此所有相应的 OnWorkerCompleted 事件处理程序都变得非常混乱;更重要的是,并非所有这些都需要完成的事件。在最坏的情况下,我将使用多个 BackgroundWorker,但我是否可以简单地从后台线程调用一个方法 (void aMethod()) 并强制它在主 UI 线程上运行?

【问题讨论】:

  • @ Jon :+1 我已经根据您的编辑更新了我的答案。希望对您有所帮助...

标签: c# .net winforms multithreading


【解决方案1】:

在 Windows 窗体控件上有一个名为 BeginInvoke 的方法,它将在 GUI 线程中执行代码。

【讨论】:

    【解决方案2】:

    我建议您使用 BackgroundWorker 线程进行后台工作,然后您可以在 OnWorkerCompleted 事件中轻松处理 UI。

    查看我的回答here了解更多信息。

    编辑

    您可以使用委托将一些任务交给 MainUI 线程。

    public delegate void MyDelegate(object paramObject);
    

    在后台线程中调用它如下。

    private void aMethod(object myParam)
    {
         if (InvokeRequired)
         {
             // We're not in the UI thread, so we need to call BeginInvoke
             BeginInvoke(new MyDelegate(aMethod), new object());
             return;
          }
    
          // Must be on the UI thread if we've got this far.
          // Do UI updates here.      
    }
    

    请参阅 herehere 以获取参考资料。

    【讨论】:

    • 感谢您的回复!我可能遗漏了一些东西,但InvokeRequired(和BeginInvoke)不需要调用控件(即aControl.InvokeRequired)?此外,您调用的 MyDelegate 具有 void (void) 的签名,但正在将 object value 作为参数传递。这可能吗?而且,您的意思是在BeginInvoke 中写UpdateMyUI 而不是UpdateStatus?就像我之前提到的,我对 C# 很陌生,所以如果我只是问了一个(或几个)愚蠢的问题,我深表歉意。 :)
    • @ Jon :感谢您指出我的错误。我发布了未经测试的代码。 aControl.InvokeRequired 是可能的。
    猜你喜欢
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多