Ben*_*jol 111 .net multithreading
我刚用这个纠正了一个bug:
_Thread.SetApartmentState(ApartmentState.STA);
Run Code Online (Sandbox Code Playgroud)
现在我想了解它的含义,以及它的工作原理!
Han*_*ant 219
COM是.NET的盛大之父.他们有很高的目标,COM所做的事情之一,但.NET完全跳过为一个类提供线程保证.COM类可以发布它具有的线程要求.COM基础架构可确保满足这些要求.
这在.NET中完全不存在.例如,你可以在多个线程中使用Queue <>对象,但是如果你没有正确锁定,你的代码中会有一个很难诊断的错误.
COM线程的确切细节太大,无法放入帖子中.我将专注于你的问题的具体细节.创建COM对象的线程必须告诉COM它希望为具有受限制的线程选项的COM类提供什么样的支持.绝大多数类只支持所谓的Apartment线程,它们的接口方法只能从创建实例的同一线程中安全地调用.换句话说,他们宣布"我不支持任何线程,请注意永远不要从错误的线程中调用我".即使客户端代码实际上不会从另一个线程调用它.
STA(Single Threaded Apartment)和MTA有两种.它在CoInitializeEx()调用中指定,该函数必须由对COM执行任何操作的任何线程调用.CLR在启动线程时自动调用该调用.对于程序的主启动线程,它从Main()方法的[STAThread]或[MTAThread]属性获取值.默认为MTA.对于您自己创建的线程,它由您对SetApartmentState()的调用决定.默认为MTA.Threadpool线程始终是MTA,无法更改.
Windows中有很多代码需要STA.值得注意的例子是Clipboard,Drag + Drop和shell对话框(如OpenFileDialog).WPF或Windows窗体项目的UI线程应始终为STA,创建窗口的任何线程也应如此.
你对COM做出的承诺,你的线程是STA,但确实要求你遵循单线程公寓合同.他们非常僵硬,当你违反合同时,你很难确定麻烦.要求是你永远不会阻塞线程任何时间,并且你需要抽一个消息循环.后一个要求由WPF或Winforms的UI线程满足,但如果您创建自己的STA线程,则需要自己处理.违反合同的常见诊断是僵局.
CLR内置了相当多的支持来支持这些要求,帮助您避免麻烦.例如,lock语句将在STA线程上阻塞时引发消息循环.大多数同步类也可以,Mutex是一个值得注意的例外.然而,这只需要处理永不阻塞的要求,您仍然需要创建自己的消息循环.WPF和Winforms中的Application.Run().
我之前提供了一个答案,其中包含有关保持COM快乐的消息循环的重要性的更多详细信息.你会在这里找到这篇文章.
| 归档时间: |
|
| 查看次数: |
26933 次 |
| 最近记录: |