-1

我正在尝试了解 C# 线程公寓并有疑问:

  1. 公寓到底是什么以及它包含什么?

  2. 公寓和 COM 线程架构

    一个进程可以有零个或多个单线程单元和零个或一个多线程单元。

    任何人都可以为应用程序提供 C# 代码示例示例或解释,其中是:

    1. 0 个 STA,0 个 MTA
    2. 1 个 STA,0 个 MTA
    3. 2 个 STA,0 个 MTA
    4. 0 个 STA,1 个 MTA
    5. 1 个 STA,1 个 MTA
    6. 2 个 STA,1 个 MTA

什么时候应该\可以使用每种情况?

4

1 回答 1

1
  1. COM 公寓是一个合乎逻辑的概念。公寓包含线程。一个 STA 单元只能包含一个线程(因此称为“单线程单元”)。一个 MTA 可以包含许多线程(因此称为“多线程单元”)。由于一个 MTA 可以包含任意数量的线程,因此一个进程中最多有一个 MTA。

  2. 您可以自己轻松编写这些示例。只需在 C# 中创建线程,并在线程入口点方法的开头调用Thread.SetApartmentState。您设置为 MTA 的任何线程都将存在于单个 MTA 中;您设置为 STA 的任何线程都将存在于它们自己的 STA 中。

不要试图摆弄线程池线程的单元状态。这些线程是共享的(它是一个池),因此尝试更改它们的工作方式并不好。此外,一旦一个线程属于一个单元,它就不能被改变。

哦,我差点忘了回答“什么时候可以/应该使用每种情况”:永远不会,如果你能帮忙的话。

即使在编写 COM 对象时,我也总是更喜欢编写“自由线程”对象(不在乎它们在哪个单元),但我可以这样做,因为我有理解线程的超能力并知道如何使用互斥锁。创建线程模型是因为(或至少部分是因为)许多早期的半专业 VB 开发人员不理解这些概念(也许仍然不理解?),因此 COM 人试图提出一个仍然可以让他们很容易做棘手的事情。

因此,当您尝试将 COM 对象从一间公寓传递到另一间公寓时会发生什么,它必须经过特殊(烦人的)魔法才能被编组;甚至从一间公寓打电话到另一间公寓也必须经过特殊(烦人的)魔法。这就是所有关于代理和存根的爵士乐的来源。如果你想了解所有这些东西是如何工作的,那么......你知道文档在哪里。但是,如果由于某种原因(例如与现有 COM 对象的互操作)不必使用它,请尽可能避免使用它。

评论中的其他问题:

我们可以为线程设置单元,使用线程的 Thread.SetApartmentState 或方法的 [STA\MTAThread] 属性。但是我们可以为对象设置公寓吗?

不,COM 对象最终属于创建它的公寓。

对其线程在 STA 单元中创建的对象的所有调用都应由该线程执行。

对于属于 STA 的对象:是和否。“否”是因为由于我之前提到的特殊(烦人的)魔法(代理和存根),您可以在 STA#2 的不同线程上获取对属于 STA#1 的 COM 对象的引用,并使从那里打电话。“是”是因为幕后发生的事情是代理/存根魔术从一个线程向另一个线程发送消息,并且该方法实际上总是在对象所属的线程上执行。因此,您可以 /initiate/ 从任何线程进行跨单元调用......但方法本身将在对象所属的线程上执行。经常出现的一个问题是,由于某种原因,代理/存根魔法不适用于给定的 COM 对象……在这种情况下,您会被卡住;

对于 MTA,它稍微宽松一些——特殊的(烦人的)编组东西只在跨越公寓边界时才起作用,而不是线程边界。因此,如果您的 MTA 中有多个线程,您必须小心自己处理同步。

于 2019-03-29T15:51:44.977 回答