c#.NET:“多线程公寓”;和“;Multithreading"

本文关键字:quot Multithreading 多线程公寓 NET 多线程 公寓 | 更新日期: 2023-09-27 18:02:13

我正在学习多线程的概念(一般和针对c# . net)。阅读不同的文章,仍然不能完全理解一些基本的概念。

我发布了这个问题。《汉斯·帕桑特》解释得很好,但我不能理解其中的一些部分。于是我开始用谷歌搜索

我读了这个没有答案的问题。

多线程和MTA一样吗?

假设我写一个WinForm应用程序是STA(如上所述的Main()方法),我仍然可以在我的应用程序中创建多个线程。我可以放心地说我的应用程序是"多线程的"。这是否也意味着我的申请是MTA?

在谈论STA/MTA时,大多数文章(像这篇)谈论的是COM/DCOM/Automation/ActiveX。这是否意味着DotNet与STA/MTA无关?

c#.NET:“多线程公寓”;和“;Multithreading"

No。MTA是一个线程的属性,就像STA一样。现在您做出了完全相反的承诺,您声明线程绝对不做任何来保持外部代码的线程安全。所以不需要有一个调度程序,你可以阻塞尽可能多,只要你喜欢。

这当然会有后果,而且可能会很不愉快。如果程序的UI线程在MTA中,这将是致命的,因为它使用了许多从根本上来说线程不安全的外部组件。剪贴板不起作用,拖放不起作用,OpenFileDialog通常只是挂起你的程序,WebBrowser不会触发它的事件。

一些组件检查这个并引发异常,但这个检查并没有一致地实现。值得注意的是,公寓状态通常只与非托管代码有关,而WPF借鉴了这个概念,并提出"调用线程必须是STA,因为许多UI组件都需要这个"。这有点误导,它真正的意思是线程必须有一个调度程序才能允许其控件工作。但在其他方面与STA承诺一致。

当组件使用COM并且作者提供了代理时,它可以工作。COM基础结构现在介入,使组件线程安全,它创建一个新的线程,它是STA,给它一个安全的家。每个方法调用都会自动封送,以便在该线程上运行,从而提供线程安全性。完全等同于Dispatcher.Invoke(),但完全自动完成。然而,这样做的后果是速度很慢,通常需要几纳秒的简单属性访问现在可能需要几微秒。

如果组件既支持MTA又支持STA,那就太幸运了。这并不常见,只有像微软这样的公司才会不遗余力地保证他们的库线程安全。

我应该强调公寓的概念在。net框架中是完全缺失的。除了陈述公寓类型的基础之外,这是必要的,因为. net程序经常需要与非托管代码进行互操作。因此,用工作线程编写Winforms应用程序是很好的,这些工作线程总是在MTA中,但是你必须自己处理线程安全问题,没有什么是自动的。

这通常是很容易理解的,几乎每个人都知道如何使用lock关键字,Task和BackgroundWorker类,并且知道Control.Begin/Invoke()方法需要从工作线程更新UI。用InvalidOperationException提醒你什么时候做错了。把它留给程序员而不是系统来处理线程安全确实会使使用线程变得更加困难。但你有很多机会比系统做得更好。这是必要的,在90年代后期的中间件战争中,Java给了这个系统提供的线程安全性一个沉重的打击。

有一些问题,但我们先从这个开始:

Apartment是COM对象初始化和执行的上下文,它可以是单线程(STA),通常用于非线程安全的对象,也可以是多线程。

术语公寓,它描述了COM在其中使用的构造创建对象

从:https://msdn.microsoft.com/en-us/library/ms809971.aspx

所以多线程和MTA不一样,但MTA是多线程的。我们可以说STA和MTA与COM对象相关。您可以在这里阅读更多内容:https://msdn.microsoft.com/en-us/library/ms693344(v=vs.85).aspx

那么,对于你的第二个问题,如果你的WinForm应用程序是"多线程"并不意味着它是"MTA"。

最后,MTA/STA概念比。net技术更老,但我们不能说它们没有任何关系,因为。net在STA和MTA中都支持COM技术。

我希望我的回答能帮助你理解Apartment和Threading的区别。

这里更有趣的阅读:你能解释一下STA和MTA吗?