简体   繁体   English

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

[英]Using AppDomains to Parallelize Non-thread-safe DLL

I have an unmanaged C++ DLL that my .NET application uses via p/invoke. 我有一个非托管的C ++ DLL,我的.NET应用程序通过p / invoke使用它。 The method that I need from this DLL is fairly time consuming and I would like to parallelize the method calls. 我需要从这个DLL的方法相当耗时,我想并行化方法调用。 The problem is that it uses a bunch of statics and globals, so it is not thread-safe (and can't be changed). 问题是它使用了一堆静态和全局变量,因此它不是线程安全的(并且不能更改)。 My plan was to overcome this non-thread-safe issue by calling the unmanaged DLL from multiple AppDomains in parallel. 我的计划是通过并行调用多个AppDomain中的非托管DLL来克服这个非线程安全问题。

I can call the unmanaged code from the multiple AppDomains without any problems as long as I don't do it in parallel, but as soon as I make the calls in parallel, I get an AccessViolationException . 只要我不并行执行,我就可以从多个AppDomain中调用非托管代码而没有任何问题,但只要我并行调用,就会得到一个AccessViolationException I am using Parallel.For() to make the parallel calls. 我正在使用Parallel.For()来进行并行调用。

Is it possible to make a non-thread-safe unmanaged DLL "thread-safe" by simply making the calls from multiple AppDomains? 是否可以通过简单地从多个AppDomain进行调用来使非线程安全的非托管DLL“线程安全”?

Calling the native method from multiple AppDomain instances won't help you at all here. 从多个AppDomain实例调用本机方法对此完全没有帮助。 AppDomain boundaries don't apply to native DLL's and they won't provide any benefit AppDomain边界不适用于本机DLL,它们不会提供任何好处

First and foremost: Load multiple copies of dll in same process 首先: 在同一进程中加载​​多个dll副本

You'd have to make sure that all invocations within an AppDomain are on a single thread. 您必须确保AppDomain中的所有调用都在一个线程上。

ParallelFor cannot make that happen, so you'd need to ParallelFor无法实现,所以你需要

  • manually parallelize (chunk up your loop for each thread/appdomain) 手动并行化(为每个线程/ appdomain填充你的循环)
  • better (IMHO): write a wrapper function that will use a specific instance of your native dll (eg by using a reference to the AppDomain from threadlocal storage?). 更好(恕我直言):编写一个包装器函数,它将使用您的本机DLL的特定实例(例如,通过使用来自threadlocal存储的AppDomain的引用?)。

Note that depending on the complexity of your situation (callbacks, use of global data in managed library) you might want to limit execution of each AppDomain to a specific CPU core (core affinity: see Begin/EndThreadAffinity ). 请注意,根据您的情况的复杂性(回调,在托管库中使用全局数据),您可能希望将每个AppDomain的执行限制为特定的CPU核心(核心关联:请参阅Begin/EndThreadAffinity )。 I might be a tad paranoid here :) 我可能在这里有点偏执:)

Wrap the C++ DLL in an EXE and parallelize process invocations (instead of running this code in threads or AppDomains). 将C ++ DLL包装在EXE中并并行化进程调用(而不是在线程或AppDomains中运行此代码)。 I had this problem with GeckoFX, which doesn't like threads, and this solution worked just fine. 我有GeckoFX这个问题,它不喜欢线程,这个解决方案工作得很好。 Of course, it's up to you to manage communication with these processes. 当然,由您来管理与这些流程的沟通。 I blogged about this some time ago. 我前段时间在博客上写过这篇文章

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

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