C#.NET:“多线程公寓";和“多线程" [英] C#.NET: "Multi Threaded Apartment" and "Multithreading"

查看:115
本文介绍了C#.NET:“多线程公寓";和“多线程"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习多线程概念(通常针对C#.NET).阅读不同的文章,仍然无法完全理解一些基本概念.

I am learning multi threading concepts (in general and targeted to C#.NET). Reading different articles, still could not fully understand few basic concepts.

我发布问题. 汉斯·帕桑特"(Hans Passant)很好地解释了这一点,但我无法理解其中的一部分.所以我开始谷歌搜索.

I post this question. "Hans Passant" explained it well but I was not able to understand some of its part. So I started googling.

我阅读了问题,但没有答案.

I read this question which have no answers.

多线程和MTA是否相同?

Is Multithreading and MTA same?

假设我编写了一个WinSTA应用程序,即STA(如上所述,其Main()方法),但仍然可以在我的应用程序中创建多个线程.我可以肯定地说我的应用程序是多线程的".这是否也意味着我的应用程序是MTA?

Suppose I write a WinForm application which is STA (as mentioned above its Main() method), still I can create multiple threads in my application. I can safely say my application is "multi-threaded". Does that also mean my application is MTA?

在谈论STA/MTA时,大多数文章(例如

While talking about STA/MTA, most of the articles (like this) talk about COM/DCOM/Automation/ActiveX. Does that mean DotNet have nothing to do with STA/MTA?

推荐答案

否.与STA一样,MTA是单线程的属性.现在,您做出完全相反的承诺,声明该线程绝对不执行任何操作以保持外部代码的线程安全.因此,无需派遣人员,您就可以根据需要阻止任意多长时间.

No. MTA is a property of a single thread, just like STA. You now make the exact opposite promise, you declare that the thread does absolutely nothing to keep external code thread-safe. So no need to have a dispatcher and you can block as much and as long as you like.

这当然会带来后果,并且可能令人非常不快.如果程序的UI线程位于MTA中,则将是致命的,因为它使用了许多根本上是线程不安全的外部组件.剪贴板不起作用,拖放操作不起作用,OpenFileDialog通常只是挂起您的程序,WebBrowser不会触发其事件.

This has consequences of course and they can be quite unpleasant. It is deadly if the UI thread of your program is in the MTA since it uses so many external components that are fundamentally thread-unsafe. The clipboard won't work, drag+drop doesn't work, OpenFileDialog typically just hangs your program, WebBrowser won't fire its events.

某些组件会对此进行检查并引发异常,但这种检查并没有始终如一地实现. WPF是值得注意的,而单元状态通常仅对非托管代码重要,WPF借用了该概念并提出调用线程必须是STA,因为许多UI组件都需要STA."这有点误导,实际上意味着线程必须具有一个调度程序才能允许其控件工作.但是在其他方面与STA承诺一致.

Some components check for this and raise an exception but this check isn't consistently implemented. WPF is notable, while apartment state normally matters only to unmanaged code, WPF borrowed the concept and raises "The calling thread must be STA, because many UI components require this." Which is a bit misleading, what it really means is that the thread must have a dispatcher to allow its controls to work. But otherwise consistent with the STA promise.

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

It can work when the component uses COM and the author has provided a proxy. The COM infrastructure now steps in to make the component thread-safe, it creates a new thread that is STA to give it a safe home. And every method call is automatically marshaled so it runs on that thread, thus providing thread-safety. The exact equivalent of Dispatcher.Invoke() but done entirely automatic. The consequence however is that this is slow, a simple property access that normally takes a few nanoseconds can now take multiple microseconds.

如果该组件支持MTA和STA,您将很幸运.这是不常见的,只有像Microsoft这样的人才能花更多的时间才能保持其库的线程安全性.

You'd be lucky if the component supports MTA as well as STA. This is not common, only somebody like Microsoft goes the extra thousand miles to keep their libraries thread-safe.

我也许应该强调,.NET Framework中完全没有公寓的概念.除了说明单元类型的基础知识以外,这是必需的,因为.NET程序通常需要与非托管代码互操作.因此,使用工作线程编写Winforms应用程序就可以了,并且那些工作线程始终位于MTA中,但是您确实需要自己处理线程安全问题,并且没有自动的方法.

I should perhaps emphasize that the concepts of apartments is entirely missing in the .NET Framework. Other than the basics of stating the apartment type, necessary since .NET programs often need to interop with unmanaged code. So writing a Winforms app with worker threads is just fine, and those worker threads are always in the MTA, you do however get to deal with thread-safety yourself and nothing is automatic.

这通常是很容易理解的,几乎每个人都知道如何使用lock关键字,Task和Background类,并且知道需要使用Control.Begin/Invoke()方法从工作线程更新UI.使用InvalidOperationException可以在错误时提醒您.由程序员而不是由系统负责线程安全的问题确实使使用线程变得更加困难.但是给您提供了很多比系统更好地做它的机会.必要的是,在90年代后期的中间件战争期间,当Java将其猛击时,这种系统提供的线程安全性遭到了严重的关注.

This is generally well-understood, just about everybody knows how to use the lock keyword, the Task and Background classes and knows that the Control.Begin/Invoke() method is required to update UI from a worker thread. With an InvalidOperationException to remind you when you get it wrong. Leaving it up to the programmer instead of the system taking care of thread-safety does make it harder to use threads. But gives you lots of opportunities to do it better than the system can. Which was necessary, this system-provided thread-safety got a serious black eye when Java punched it in the face during the middleware wars of the late 90s.

这篇关于C#.NET:“多线程公寓";和“多线程"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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