没有第二种形式的多线程消息泵送

时间:2009-09-15 16:01:38

标签: c# com multithreading synchronizationcontext

我有一个使用COM组件的C#应用​​程序。此COM组件需要消息泵(Application.Run())来执行其处理。这意味着它一直停留在主线程上。但我最近发现可以在另一个获得自己的ApplicationContext的线程上启动另一个Application.Run。

所以我想在它自己的Application.Run()中的自己的线程上托管COM组件,但我无法弄清楚如何在不创建UI表单的情况下在新线程上启动。

我需要与线程通信的WindowsFormsSynchronizationContext在Application.Run()之前不会被创建。但是一旦调用了Application.Run(),我就无法弄清楚如何获得SynchronizationContext。如果我可以在该线程上引发单个事件,我可以使用它来引导整个事物(创建COM对象等),但似乎没有任何地方可以挂钩到没有表单的新事件循环

我尝试过各种令人费解的事情,比如安装消息过滤器(新线程上没有消息),将执行上下文复制到另一个线程并尝试从那里检索SynchronizationContext(它拒绝复制已经运行的线程的ExecutionContext,在启动Application.Run()之前检索Thread.CurrentContext然后调用DoCallbBack()(DoCallback最终在原始线程上)等等。我没有尝试过任何工作。

1 个答案:

答案 0 :(得分:6)

布莱斯,

您可以从Anders Hejlsberg's talk about "The Future of C#".调整此片段。这是一个向线程添加消息泵的小类,以便他可以使用REPL循环打开窗口,并且它们将附加消息泵

代码如下所示:

using System.Windows.Forms;
using System.Threading;
class UserInterfaceThread()
{
    static Form window;

    public UserInterfaceThread() 
    {
        var thread = new Thread(() => {
            window = new Form();
            var handle = window.Handle;
            Application.Run();
            });
        thread.Start();
    }
    public void Run(Action action)
    {
        window.Invoke(action);
    }
}

有关此代码的讨论发生在Anders演讲的1小时5分钟,如果您想查看它。