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

Bry*_*ner 4 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最终在原始线程上),等等.我没有尝试过.

Rob*_*vey 6

布莱斯,

您可以从Anders Hejlsberg关于"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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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