Winforms 需要关于COM与TPL行为的帮助吗
我需要一些帮助来理解STA和MTA在winform和console应用程序方面的区别。我使用第三方COM接口并行执行函数,使用parallel.invoke。当我在控制台应用程序中执行此操作时,一切正常,代码实际上并行运行。但是,当我在Winform中执行相同的操作时,它是按顺序进行的,如果我删除Winform入口点上方的stathread标记,它将开始并行工作。有人能解释这种行为吗?有什么建议就好了 STA和MTA都是COM/ActiveX的“线程模型”,可以追溯到20世纪90年代中期 这里有一个很好的链接:Winforms 需要关于COM与TPL行为的帮助吗,winforms,com,console,task-parallel-library,Winforms,Com,Console,Task Parallel Library,我需要一些帮助来理解STA和MTA在winform和console应用程序方面的区别。我使用第三方COM接口并行执行函数,使用parallel.invoke。当我在控制台应用程序中执行此操作时,一切正常,代码实际上并行运行。但是,当我在Winform中执行相同的操作时,它是按顺序进行的,如果我删除Winform入口点上方的stathread标记,它将开始并行工作。有人能解释这种行为吗?有什么建议就好了 STA和MTA都是COM/ActiveX的“线程模型”,可以追溯到20世纪90年代中期 这里有
- STA:
- MTA:
- STA:
- MTA:
一个问题是为组件选择最佳线程模型(默认为STA、IIRC)。另一个问题是,如果需要在组件和使用不同线程模型的组件之间封送数据,运行时将做什么。上面的链接讨论了这两个方面。COM有一个在.NET中完全缺失的功能。COM类可以指定它是否是线程安全的。它使用注册表中名为ThreadingModel的项来执行此操作。与大多数.NET类一样,绝大多数COM类都不是线程安全的,因此它们指定“单元”。这是一个有点晦涩的术语,意味着“只从创建我的线程中调用我”。自动提供线程安全性 为了实现这一点,创建COM对象的线程必须指明它愿意为非线程安全的COM类提供何种支持。STA线程是一个安全的家。要求是线程像任何UI线程一样泵送一个消息循环。消息循环是COM封送从工作线程到创建对象的线程的调用的机制。加入MTA的线程明确表示它不提供支持 COM必须对MTA线程做些什么,因为它们不适用于线程不安全的COM对象。它创建一个新线程,一个STA线程,为COM对象提供一个安全的家。这是非常低效的,每个方法调用都必须被封送。而且风险很大,如果COM类的对象在内部共享状态,那么它仍然可能是线程不安全的 因此,在Winforms案例中,您在主线程上创建了所有对象,这是一个STA。并从并行工作线程发出调用,这些调用都被封送并序列化回STA线程。不可避免地,它们一个接一个地执行,而您得不到并发性 在控制台中,您在MTA线程上创建了它们。因此COM被迫为每个对象创建线程。对工作线程的方法调用仍然被封送,但现在被封送到多个线程。因此,现在您确实获得了并发性,但代价是大量额外的线程。以及服务器内部共享状态时出现故障的风险
通过在工作线程上创建COM对象,使Winforms案例与控制台案例相同。一定要对它进行彻底的测试。COM有一个.NET中完全没有的功能。COM类可以指定它是否是线程安全的。它使用注册表中名为ThreadingModel的项来执行此操作。与大多数.NET类一样,绝大多数COM类都不是线程安全的,因此它们指定“单元”。这是一个有点晦涩的术语,意味着“只从创建我的线程中调用我”。自动提供线程安全性 要做到这一点