使用AppDomains并行化非线程安全的DLL

时间:2011-05-15 21:52:27

标签: c# .net pinvoke parallel-processing appdomain

我有一个非托管的C ++ DLL,我的.NET应用程序通过p / invoke使用它。我需要从这个DLL的方法相当耗时,我想并行化方法调用。问题是它使用了一堆静态和全局变量,因此它不是线程安全的(并且不能更改)。我的计划是通过并行调用来自多个AppDomain的非托管DLL来克服这个非线程安全的问题。

我可以从多个AppDomain中调用非托管代码而不会出现任何问题,只要我不并行执行,但只要我并行调用,就会得到AccessViolationException。我正在使用Parallel.For()进行并行调用。

是否可以通过简单地从多个AppDomain进行调用来使非线程安全的非托管DLL“线程安全”?

3 个答案:

答案 0 :(得分:7)

从多个AppDomain实例调用本机方法对此无济于事。 AppDomain边界不适用于本机DLL,并且它们不会提供任何好处

答案 1 :(得分:2)

首先:Load multiple copies of dll in same process

您必须确保AppDomain中的所有调用都在一个线程上。

ParallelFor无法实现,所以你需要

  • 手动并行化(为每个线程/ appdomain填充循环)
  • 更好(恕我直言):编写一个包装器函数,它将使用您的本机dll的特定实例(例如,通过使用来自threadlocal存储的AppDomain的引用?)。

请注意,根据您的情况的复杂性(回调,在托管库中使用全局数据),您可能希望将每个AppDomain的执行限制为特定的CPU核心(核心关联:请参阅Begin/EndThreadAffinity)。我可能在这里有点偏执:)

答案 2 :(得分:0)

将C ++ DLL包装在EXE中并并行化进程调用(而不是在线程或AppDomains中运行此代码)。我有GeckoFX这个问题,它不喜欢线程,这个解决方案工作得很好。当然,由您来管理与这些流程的沟通。我前一段时间blogged about this