使用 AppDomains 并行化非线程安全的 DLL
本文关键字:安全 DLL 线程 AppDomains 并行化 使用 | 更新日期: 2023-09-27 17:56:25
我有一个非托管的C++DLL,我的.NET应用程序通过p/invoke使用。 我需要从这个 DLL 中获取的方法相当耗时,我想并行化方法调用。 问题是它使用一堆静态和全局变量,所以它不是线程安全的(并且无法更改)。 我的计划是通过从多个 AppDomain 并行调用非托管 DLL 来克服这个非线程安全问题。
只要我不并行调用,我就可以毫无问题地从多个 AppDomain 调用非托管代码,但是一旦并行调用,我就会得到AccessViolationException
。 我正在使用 Parallel.For() 进行并行调用。
是否可以通过简单地从多个 AppDomain 进行调用来使非线程安全的非托管 DLL "线程安全"?
从多个AppDomain
实例调用本机方法在这里根本无济于事。 AppDomain
边界不适用于本机 DLL,它们不会提供任何好处
首先也是最重要的:在同一进程中加载多个 dll 副本
您必须确保AppDomain中的所有调用都在单个线程上。
ParallelFor 无法做到这一点,所以你需要
- 手动并行化(为每个线程/应用域将循环分块)
- 更好(恕我直言):编写一个包装器函数,该函数将使用本机 DLL 的特定实例(例如,通过使用对线程本地存储中 AppDomain 的引用?
请注意,根据您的情况的复杂性(回调、在托管库中使用全局数据),您可能希望将每个 AppDomain 的执行限制为特定的 CPU 内核(核心关联:请参阅Begin/EndThreadAffinity
)。我在这里可能有点偏执:)
将
C++ DLL 包装在 EXE 中并并行化进程调用(而不是在线程或应用程序域中运行此代码)。我在 GeckoFX 上遇到了这个问题,它不喜欢线程,这个解决方案工作得很好。当然,管理与这些流程的通信取决于您。我前段时间在博客上写过这个。