这种情况下需要STA消息循环吗? [英] Is STA Message Loop Required in This Case?

查看:14
本文介绍了这种情况下需要STA消息循环吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 COM 对象正在创建并在 .NET 应用程序的线程上运行.线程被标记为单线程公寓,一切似乎都在工作.我的理解是,如果这些线程尝试从主线程访问 COM 对象,那么这些对象将在 .NET 中自动为我编组和序列化,因此即使在这种情况下,事情也会为我处理,一切安全整洁,尽管可能有点慢.

I've got some COM objects I'm creating and running on threads in a .NET application. The threads are marked as Single Threaded Apartments, and everything seems to be working. My understanding is that if these threads try to access COM objects from the main thread then those objects will automatically be marshaled and serialized for me in .NET, so even in that case things will be handled for me, all safe and neat, though maybe a bit slowly.

我的问题是,虽然事情似乎运行良好,但我没有在我正在创建的 STA 线程中注入消息循环.如果可以的话,我宁愿避免消息循环,因为它会导致额外的复杂性(以及可能的效率损失).

My question is, while things appear to be working fine, I am not pumping a message loop in the STA threads I'm creating. I'd rather avoid the message loop if I can because of the extra complications it would cause (and possible efficiency losses as well).

我已经阅读了很多关于为什么需要消息循环的建议(主要来自非常有帮助的 Hans Passant),我的理解是消息循环在线程 A 上提供了一个其他线程 B 可以请求的位置生活在线程 A 上的 COM 对象可以被编组和播放.如果这是正确的,那么只要没有其他线程从线程 A 上的 COM 对象请求任何内容,线程 A 在不发送消息循环时是否安全?还是在其他情况下消息循环也可能发挥作用?

I've read a bunch of advice on why the message loop is necessary (mostly from the very helpful Hans Passant), and my understanding is that the message loop gives a place on a thread A where some other thread B can request that COM objects living on thread A can be marshaled and played with. If that's correct, then as long as no other threads request anything from the COM objects on thread A, is Thread A safe in not pumping a message loop? Or are there other cases where the message loop might come into play as well?

我在这里玩火吗?有没有这样的情况,你问你是不是在玩火,而你不是?

Am I playing with fire here? And is there ever a case where you ask if you're playing with fire and you're not?

推荐答案

STA 合约需要抽一个消息循环.但是,是的,不抽水是有可能逃脱的.有两个主要问题可能会出错:

The STA contract requires pumping a message loop. But yes, it is possible to get away with not pumping. There are two major things that can go wrong:

  • 从另一个单元(包括另一个 STA 线程或 MTA 中的线程)对接口方法进行的任何调用都不会完成.这看起来像您的程序中的死锁,调用根本不会返回.请注意,您可以很好地控制自己的调用,但您不知道 COM 组件在做什么.它很可能会启动一个线程本身.您可以使用 Debug + Windows + Threads 在调试器中看到这一点.确保您在非托管模式下运行调试器,并且您可以考虑您看到的所有线程.顺便说一句,不是特别容易.

  • Any call that's made on an interface method from another apartment, including another STA thread or a thread in the MTA will not complete. This looks like deadlock in your program, the call simply never returns. Beware that you can control your own calls quite well but you don't know what the COM component is doing. It may well start a thread itself. You can see this in the debugger with Debug + Windows + Threads. Make sure you are running the debugger in unmanaged mode and that you can account for all the threads you see. Not particularly easy btw.

许多单元线程 COM 组件依靠消息循环来满足自己的需求.它可能是一个无害的定时器,当没有循环时它不会滴答作响.或者它可能会在内部进行编组.使用 Spy++ 并检查您的新 STA 线程是否拥有任何隐藏的窗口,如果您看到一个,肯定是有问题的迹象.诊断只是行为不端的组件.不引发事件是一种常见的不幸.

Many apartment threaded COM components count on having a message loop taking care of their own needs. It could be something innocuous as a Timer, it won't tick when there's no loop. Or it may do marshaling internally. Use Spy++ and check if there are any hidden windows owned by your new STA thread, sure sign of trouble if you see one. The diagnosis is the component just misbehaving. Not raising events is a common mishap.

如果您对服务器的内部结构知之甚少,就没有什么可钉在墙上的了.一定要测试一下.

Nothing really to nail to a wall when you don't know enough about the internals of the server. Be sure to test the heck out of it.

这篇关于这种情况下需要STA消息循环吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆