繁体   English   中英

.NET 4任务并行库可以使用COM对象吗?

[英]Can the .NET 4 Task Parallel Library use COM objects?

这是“这有可能吗,如果可以,您能给我一个简单的例子,因为我无法在线找到一个吗?” 这样的问题。

我有许多完全独立的(即“令人尴尬的并行”)进程,我想使用C#在.NET Framework 4中使用Task Parallel库并行运行。 其中某些过程需要使用可通过COM / OLE自动化访问的软件。

具体来说,有一个Parallel.Foreach()循环将任务从项目列表中分离出来,基本上是在Parallel.Foreach内部调用一个不同的函数来处理处理(因此其中一些函数使用COM库来工作)。

这可能吗? 谢谢。

在TPL中使用COM对象的可能性为100%。 的确,默认情况下,TPL将使用标准的.NET ThreadPool,而TPL通过TaskScheduler具有扩展点, 扩展点使您能够提供自己的调度程序,该调度程序可以将工作分派到已创建的线程。

在使用COM对象的情况下,首先需要知道COM类是否需要STA线程或MTA线程。 如果使用MTA线程,则不需要做任何特殊的事情,因为COM类已经可以从任何随机线程中使用。 不幸的是,大多数经典的COM对象都倾向于依赖STA线程,那是在您需要使用自定义TaskScheduler时候,以便您使用它们的任何.NET线程都已初始化为STA兼容线程

尽管TaskSchedulers编写起来并不简单,但是如果您对线程有基本的了解,他们也不难编写。 幸运的是,ParallelExtensions Extras库已经提供了一个StaTaskScheduler类,因此您甚至不需要自己编写任何内容。 PFX团队在这里一篇很棒的博客文章 ,讨论了StaTaskScheduler类的实现和一些用例。

但是基本上,你要初始化一个新StaTaskScheduler作为你的类的一个静态的地方,然后就开始你的Tasks指定,他们是由例如调度。 看起来像这样:

// Create a static instance of the scheduler specifying some max number of threads
private static readonly StaTaskScheduler MyStaTaskScheduler = new StaTaskScheduler(4);

....

// Then specify the scheduler when starting tasks that need STA threading
Task.TaskFactory.StartNew(
() =>
{
    MyComObject myComObject = new MyComObject();

    myComObject.DoSomething();

    // ... etc ...
},
CancellationToken.None,
TaskCreationOptions.None,
MyStaTaskScheduler);

这是可能的,但也可能不起作用。

许多COM对象需要特定的单元线程 当您使用Parallel.For / ForEach时,您正在.NET ThreadPool上运行,该程序没有单元线程设置。 这可能有效,并且对于某些COM对象可能有效,但也可能导致崩溃和难以跟踪的奇怪COM异常。

我需要验证一些其他信息,但这可能会有所帮助。 默认的任务计划程序将使用当前线程来执行某些工作,然后根据需要从线程池中添加其他线程。

如果在执行Parallel.ForEach时共享一个COM对象,则可能会导致问题。 例如,假设您的主线程是STA。 您实例化该对象上的COM对象,并使用Parallel.ForEach进行一些工作,每个线程尝试访问先前实例化的COM对象。 我怀疑它会破裂,初步测试似乎可以证明这一点。 在这种情况下,我至少看到两个选择:

  • 假设COM对象支持MTA,则使调用线程使用MTA。 但是,由于其他原因,这可能不是一个选择。 例如,如果该应用程序是Windows Forms应用程序,则我认为Main()必须具有STAThread属性。
  • 使用替代任务计划程序,例如Drew提到的StaTaskScheduler。 您可以具有所有STA线程,也可以使用不使用调用线程并运行所有MTA线程的调度程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM