Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.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#中为COM STA线程泵送消息?_C#_Com_Message_Sta_Doevents - Fatal编程技术网

如何在C#中为COM STA线程泵送消息?

如何在C#中为COM STA线程泵送消息?,c#,com,message,sta,doevents,C#,Com,Message,Sta,Doevents,我有一个主STA线程,在COM对象上调用很多方法,还有一个辅助STA线程,在同一个对象上也做很多工作。我希望主线程和次线程并行工作(即,我期望主线程和次线程的交错输出)。我知道我需要不时地在主线程中发送消息——用C++调用get /平移/调度消息将起到作用。 但我在C#中使用相同的策略时遇到了问题。首先,我在主线程中使用CurrentThread.Join()来控制第二个线程。它不起作用。然后我转向Application.DoEvents()——每当我想让第二个线程运行时,我就在主线程中调用它。

我有一个主STA线程,在COM对象上调用很多方法,还有一个辅助STA线程,在同一个对象上也做很多工作。我希望主线程和次线程并行工作(即,我期望主线程和次线程的交错输出)。我知道我需要不时地在主线程中发送消息——用C++调用get /平移/调度消息将起到作用。 但我在C#中使用相同的策略时遇到了问题。首先,我在主线程中使用CurrentThread.Join()来控制第二个线程。它不起作用。然后我转向Application.DoEvents()——每当我想让第二个线程运行时,我就在主线程中调用它。结果是第二个线程很快就抓住了控件,并且不会放手——直到第二个线程全部完成,主线程才能继续

我阅读的文档中说Application.DoEvents()将处理所有等待的事件,而GetMessage()只检索一条消息

正确的做法是什么?是否有C#等效于Get/Translate/DispatchMessage

谢谢

更新:第二个线程运行太快,向主STA线程发送大量COM调用消息。我只是在第二个线程中添加了延迟来降低速度。现在两个线程基本上是并行运行的。
但我仍然想知道是否有C等价于GETMeals/TrimeMeSea/Debug Cuff.< /P> < P>您原来的C++代码违反了STA合同。它表示必须将接口指针从一个线程封送到另一个线程,以便仅从一个线程对对象进行所有调用。对于单线程COM服务器来说,这是一个困难的要求,不这样做会带来与多线程对非线程安全代码进行调用相关的典型痛苦。使用两个STA线程并不能免除此要求,对象仅由创建它的线程拥有。第二个线程只是另一个线程,无法安全地进行调用,因为服务器不支持多线程

你不知怎么地在C++代码中侥幸逃脱了,很难想象不时有毛病。COM不能在进程内COM服务器上强制执行STA协定,只能在进程外服务器上强制执行STA协定。在这种情况下,违反合同会生成RPC_E_错误的线程

不管怎样,你再也不能在C#程序中侥幸逃脱了。CLR会自动为您封送接口指针。您在第二个线程上进行的调用将被封送到拥有该对象的STA线程。仍然存在交错,但只有当第一个线程空闲并重新进入消息循环时,才能传递第二个线程的调用。没有解决方法,接口指针的CLR处理严格按照规则进行


我想这会给你的代码带来很多后果,最大的一个后果是第二个线程真的不能完成任何事情了。没有并发性,对对象的所有调用都严格序列化。而且是线程安全的。您最好只从一个线程进行所有调用,这样您就不必担心死锁带来的巨大风险。作为奖励,让适当的信息传递变得不那么重要。如果第二个线程执行其他关键工作,那么利用COM对单线程代码的支持会很有帮助。

在.Net中获取/翻译/分派时,您应该能够调用或(取决于您使用的是winforms还是wpf)帮助线程。这将在调用Get/Trans/Dispatch的线程上为您泵送一个消息循环。如果您不喜欢这种想法,那么您可以P/调用Win32调用


尽管.Net会根据答案让几乎所有的东西都能为您工作,但实际上我发现来自COM对象的消息可能会导致UI线程结巴,因为底层的DispatchMessage()似乎需要很长时间(当然比我预期的要长,或者可以解释)。我们改变了解决方案,在helper线程上创建COM对象,并显式地从UI线程封送对它的调用