多个线程可以设置 STA 单元吗?
Posted
技术标签:
【中文标题】多个线程可以设置 STA 单元吗?【英文标题】:Can more than one thread have STA apartment set? 【发布时间】:2012-12-03 16:04:28 【问题描述】:我正在考虑使用此代码来检测线程是否是主 (UI) 线程。
public static bool IsMainThread()
return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA;
当工作线程运行返回 false 的任务时,它看起来确实可以正常工作,只是想知道它是否通常为 true。
如果相关,这是一个 WPF 应用程序。
这与我的另一个问题类似:How do I assert that the code is running in the main thread? 但没有人建议此解决方案。
【问题讨论】:
【参考方案1】:是的,您可以在创建其他线程时设置 STA。线程池线程在 MTA 中。
【讨论】:
但是除非我明确地这样做,否则不会出现多线程是STA的情况? 如果您控制应用程序中的所有线程创建,那么您是正确的,只有主线程将是 STA - .NET 中的线程默认为 MTA。如果您托管任何 COM 组件,或者您正在使用一个库,那么您最终可能会得到您不知道的 STA 线程。 调度程序上没有什么东西可以让您更可靠地检测到这一点吗? 是的,将当前线程调度程序与对主线程调度程序的缓存引用进行比较似乎是前进的方向。【参考方案2】:是的,您可以让多个线程拥有 STA 单元。但是你不能在线程之间交换框架元素,这仍然会导致错误。这意味着您不能制作文本框控件并将其填充到也是 STA 的工作线程中,然后将其传递给您的主线程(也是 STA)并将其添加到表单中。这仍然会导致错误。那么问题来了,为什么要给STA设置多个线程呢?
【讨论】:
我不想。我只是想要一种检测主线程的方法。如果多个线程设置 STA 的可能性极小/不常见,那么这可能就足够了。【参考方案3】:根据 STAThreadAttribute 的文档,您不能拥有多个 STA 线程(除非您使用 COM 互操作,否则您甚至不能真正拥有一个)。
“将此属性应用于入口点方法(C# 和 Visual Basic 中的 Main() 方法)。它对其他方法没有影响。”
从 .Net 2.0 开始,单线程单元仅适用于执行 COM 互操作。
“COM 线程模型仅适用于使用 COM 互操作的应用程序。在不使用 COM 互操作的应用程序中使用此属性无效。”
“在 .NET Framework 2.0 版中,如果新线程在启动前未设置其单元状态,则将其初始化为 ApartmentState.MTA。主应用程序线程默认初始化为 ApartmentState.MTA。”
参考:http://msdn.microsoft.com/en-us/library/system.stathreadattribute(v=vs.100).aspx
【讨论】:
以上是关于多个线程可以设置 STA 单元吗?的主要内容,如果未能解决你的问题,请参考以下文章
ThreadThreading.TimerTask中ShowDialog()方法报错:“在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式”
ThreadThreading.TimerTask中ShowDialog()方法报错:“在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式”
菜鸟解决 必须将当前线程设置为单线程单元(STA)模式的报错
在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记。 多线程操作剪切板的时候。
FolderBrowserDialog 关于设置为单线程单元(STA)模式的问题
选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器