我有一个使用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最终在原始线程上)等等。我没有尝试过任何工作。
答案 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分钟,如果您想查看它。