一个MTA控制台应用程序中调用多个线程一个STA COM对象 [英] An MTA Console application calling an STA COM object from multiple threads

查看:207
本文介绍了一个MTA控制台应用程序中调用多个线程一个STA COM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然有关于COM和STA / MTA(如这里)很多问题,其中大多数是讲它有一个应用程序UI。但是,我有以下设置:

Although there are many questions about COM and STA/MTA (e.g. here), most of them talk about applications which have a UI. I, however, have the following setup:


  • 控制台应用程序,默认情况下是多线程单元(main()的明确有 [MTAThread] 属性)。

  • 主线程派生了一些工作线程。

  • 的主线程实例化一个单线程COM对象。

  • 主线程调用到Console.ReadLine(),直到用户点击'q',该应用程序后终止。

  • A console application, which is by default Multi-Threaded Apartment (Main() explicitly has the [MTAThread] attribute).
  • The main thread spawns some worker threads.
  • The main thread instantiates a single-threaded COM object.
  • The main thread calls Console.ReadLine() until the user hits 'q', after which the application terminates.

几个问题:


  • 许多地方提​​到的需要COM消息泵的对象。我是否需要手动创建一个消息泵主线程,或将CLR创建它,我在一个新的STA线程,因为这个< ?/ A>问题建议

  • 只是为了确保 - 假设CLR自动地创建必要的管道,我可以再使用任何辅助线程COM对象,而无需显式同步的

  • 以下哪是在性能方面更好:
    • Numerous places mentions the need of a message pump for COM objects. Do I need to manually create a message-pump for the main thread, or will the CLR create it for me on a new STA thread, as this question suggests?
    • Just to make sure - assuming the CLR automagically creates the necessary plumbing, can I then use the COM object from any worker thread without the need of explicit synchronization?
    • Which of the following is better in terms of performance:
      • Let the CLR take care of the marshaling to and from the COM object.
      • Explicitly instantiate the object on a separate STA thread, and have other thread communicate with it via e.g. a ConcurrentQueue.

      推荐答案

      是的,它是能够从 MTA 的螺纹

      Yes, it is possible to create a STA COM object from an MTA thread.

      在这种情况下,<青霉创建<青霉> STA 的COM对象> COM 的(不是的 CLR 的)将创建一个隐式公寓STA(独立的COM拥有的线程)或重新使用现有的,创造更早期。 COM对象将在那里实例化,然后线程安全代理对象(COM编组包装器)将为其创建并返回到MTA线程。到MTA线程上所做的所有对象调用由COM到隐STA公寓被整理。

      In this case, COM (not CLR) will create an implicit STA apartment (a separate COM-owned thread) or re-use the existing one, created ealier. The COM object will be instantiated there, then a thread-safe proxy object (COM marshalling wrapper) will be created for it and returned to the MTA thread. All calls to the object made on the MTA thread will be marshalled by COM to that implicit STA apartment.

      这情况通常是不可取的。它有很多缺点并且可能根本不起作用,如果COM不能编组对象的一些接口。检查这个问题了解更多详情。此外,消息泵循环,由隐STA公寓运行,泵仅特定的COM的消息的数量有限。这也可能会影响在COM的功能。

      This scenario is usually undesirable. It has a lot of shortcomings and may simply not work as expected, if COM is unable to marshal some interfaces of the object. Check this question for more details. Besides, the message pump loop, run by the implicit STA apartment, pumps only a limited number of COM-specific messages. That may also affect the functionality of the COM.

      您可以尝试它,它可能为你工作好。或者,你可能会遇到一些不愉快的问题,如死锁,很难诊断

      You may try it and it may work well for you. Or, you may run into some unpleasant issues like deadlocks, quite difficult to diagnose.

      下面是一个密切相关的问题,我刚刚回答:

      Here is a closely related question I just recently answered:

      StaTaskScheduler和STA线程消息抽水

      我个人更喜欢手动控制线程间的调用和线程亲和力的逻辑,与类似的 ThreadAffinityTaskScheduler 我的回答提出的。

      I'd personally prefer to manually control the logic of the inter-thread calls and thread affinity, with something like ThreadAffinityTaskScheduler proposed in my answer.

      您可能还需要阅读: INFO:OLE线程模型的说明和工作原理的,强烈推荐

      You may also want to read this: INFO: Descriptions and Workings of OLE Threading Models, highly recommended.

      这篇关于一个MTA控制台应用程序中调用多个线程一个STA COM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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