Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无第二种形式的多线程消息泵送_C#_Com_Multithreading_Synchronizationcontext - Fatal编程技术网

C# 无第二种形式的多线程消息泵送

C# 无第二种形式的多线程消息泵送,c#,com,multithreading,synchronizationcontext,C#,Com,Multithreading,Synchronizationcontext,我有一个使用COM组件的C#应用程序。此COM组件需要一个消息泵(Application.Run())来进行处理。这意味着它被卡在了主线程上。但我最近发现,可以启动另一个应用程序。在另一个线程上运行,该线程拥有自己的ApplicationContext 因此,我想将COM组件托管在它自己的应用程序.Run()中的自己的线程上,但我不知道如何在不创建UI表单的情况下在新线程上启动 我需要与线程通信的WindowsFormsSynchronizationContext在Application.Run

我有一个使用COM组件的C#应用程序。此COM组件需要一个消息泵(Application.Run())来进行处理。这意味着它被卡在了主线程上。但我最近发现,可以启动另一个应用程序。在另一个线程上运行,该线程拥有自己的ApplicationContext

因此,我想将COM组件托管在它自己的应用程序.Run()中的自己的线程上,但我不知道如何在不创建UI表单的情况下在新线程上启动

我需要与线程通信的WindowsFormsSynchronizationContext在Application.Run()之前不会被创建。但是一旦调用Application.Run(),我就不知道如何获取SynchronizationContext。如果我可以在该线程上引发一个事件,我可以使用它来引导整个过程(创建COM对象等),但是似乎没有任何地方可以在没有表单的情况下钩住新的事件循环

我尝试过各种复杂的事情,比如安装消息过滤器(在新线程上不会引发任何消息),将执行上下文复制到另一个线程中,并尝试从那里检索SynchronizationContext(它拒绝复制已经运行的线程的ExecutionContext),在启动Application.Run()之前检索Thread.CurrentContext,然后调用DoCallbBack()(DoCallback最终位于原始线程上),等等。我尝试过的方法都不管用。

Bryce

您可能可以修改这个代码段,它是一个向线程添加消息泵的小类,这样他就可以使用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分钟,如果您想查看它的话。

因此,创建窗口句柄是实例化SynchronizationContext而不是Application.Run()的原因。因此,在调用Application.Run()之前,只需调用“IntPtr handle=new Form().handle;”即可创建所需的WindowsFormsSynchronizationContext。多谢。