- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚刚使用此方法纠正了一个错误:
_Thread.SetApartmentState(ApartmentState.STA);
现在我想了解它的含义以及它为何有效!
最佳答案
COM 是 .NET 的鼻祖。他们对此有相当崇高的目标,COM 所做但 .NET 完全跳过的事情之一是为类提供线程保证。 COM 类可以发布它具有何种线程要求。 COM 基础结构可确保满足这些要求。
这在 .NET 中是完全不存在的。例如,您可以在多个线程中使用 Queue<> 对象,但如果您没有正确锁定,您的代码中将会出现一个很难诊断的严重错误。
COM 线程的具体细节太大,一篇文章无法容纳。我将重点讨论您问题的具体内容。创建 COM 对象的线程必须告诉 COM 它想要为具有受限线程选项的 COM 类提供哪种支持。这些类中的绝大多数仅支持所谓的单元线程,它们的接口(interface)方法只能从创建实例的同一线程安全地调用。换句话说,他们宣布“我不支持任何线程,请注意永远不要从错误的线程调用我”。即使客户端代码实际上确实从另一个线程调用它。
有两种,STA(单线程单元)和MTA。它在 CoInitializeEx() 调用中指定,该函数必须由任何使用 COM 执行任何操作的线程调用。 CLR 每当启动线程时都会自动进行该调用。对于程序的主启动线程,它从 Main() 方法上的 [STAThread] 或 [MTAThread] 属性获取要传递的值。默认为 MTA。对于您自己创建的线程,它由您对 SetApartmentState() 的调用决定。默认为 MTA。线程池线程始终是 MTA,无法更改。
Windows 中有很多代码需要 STA。您自己使用的著名示例是剪贴板、拖放和 shell 对话框(如 OpenFileDialog)。还有很多您看不到的代码,例如 UI 自动化程序和用于观察消息的 Hook 。这些代码都不必是线程安全的,其作者在不知道它在哪个程序中使用的情况下很难使其安全。因此,WPF 或 Windows 窗体项目的 UI 线程必须始终是 STA 才能支持此类代码,创建窗口的任何线程也是如此。
您向 COM promise 您的线程是 STA,但是确实要求您遵循单线程公寓契约。它们非常僵硬,当你违反契约(Contract)时,你可能很难诊断出问题。要求是永远不要阻塞线程任何时间并且泵送消息循环。 WPF 或 Winforms 的 UI 线程可以满足后一个要求,但如果您创建自己的 STA 线程,则需要自己处理。违反契约(Contract)的常见诊断是僵局。
顺便说一句,CLR 内置了相当多的支持来支持这些要求,帮助您避免麻烦。 lock 语句和 WaitOne() 方法在 STA 线程上阻塞时会泵送消息循环。然而,这只能满足永不阻塞的要求,您仍然需要创建自己的消息循环。 WPF 和 Winform 中的 Application.Run()。
我之前贡献过一个答案,其中包含有关使用消息循环来保持 COM 满意的重要性的更多详细信息。您会发现post here .
关于.net - ApartmentState 傻瓜书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4154429/
我想完全理解 Java 上的二维 RTree,但我在解释中迷路了,我希望有人能告诉我它们是如何工作的。 我对他们的了解是这样的: 您从具有最大条目数 M 的节点列表开始,当您尝试获得更多值时,您必须拆
我想与 4 个国家足球队(英格兰、比利时、德国和法国)和 n 个日期一起工作 Date Matches 16.03 England X Brazil 16.03
NSInvocation 究竟是如何工作的?有好的介绍吗? 我在理解以下代码(来自 Cocoa Programming for Mac OS X,第 3 版)的工作原理方面特别有问题,但我也能够独立于
我正在尝试学习如何在亚马逊云上成功部署 Symfony2 应用程序。有用的是我从空白的 Ubuntu 开始,安装了 lamp-server^、svn ……其他一些好东西,它运行得很好。 问题:所有 A
我一直在努力了解 getter 和 setter,但没有深入了解。我读过 JavaScript Getters and Setters和 Defining Getters and Setters只是没
如果我没看错,那么 Controller 的功能就是处理 POST 数据,并在技术上通过模型对应用程序(例如数据库)的状态进行更改。 据我了解,View 也从 Model 获取数据。 这就是我对工作流
我正在尝试将日期从一种格式转换为另一种格式:来自例如“2005 年 10 月 29 日”至 2005-10-29。我有一个包含 625 个日期的列表。我使用 Awk。 大多数情况下,转换都有效。然而,
我是一名优秀的程序员,十分优秀!