几个AppDomains和本机代码

Had*_*man 11 .net c# multithreading native appdomain

我的C#应用​​程序使用的本机代码不是线程安全的.

我可以运行该本机代码的多个进程,使用进程间通信来实现并发.

我的问题是,我是否可以使用App Domains,以便多个托管线程(每个托管在不同的应用域上)将调用本机代码并且它们不会相互干扰?

主要目标是防止过程分离.

Han*_*ant 13

不,AppDomains是纯托管代码概念.它通过将托管对象根保持独立来实现隔离.一个AppDomain无法看到另一个AppDomain的对象,因此可以非常安全地中止代码和卸载程序集.从不发生意外,它会丢弃可能包含状态的所有数据.

非托管代码与GC堆完全无关,因此AppDomains将在其数据部分和自己的本机堆(HeapAlloc)中进行分配.这种分配是全球流程的.这使得进程成为隔离边界,您需要一个辅助进程来加载DLL并与其中一个.NET进程互操作机制(套接字,命名管道,内存映射文件,远程处理,WCF)进行通信.

从技术上讲,您可以创建DLL的副本,每个副本都有不同的名称.但是由于你不能再使用[DllImport],因此它的扩展非常糟糕且pinvoke非常笨拙.您需要为每个导出的函数提供委托声明,并使用LoadLibrary()和GetProcAddress()来初始化委托对象.


Adr*_*tti 4

是的,可以做到,但你应该认真衡量努力是否得到回报。

Windows 不会加载非托管DLL 的多个副本,并且非托管 DLL 是按进程(而不是按AppDomain)加载的。您可以做的是创建同一 DLL 的多个临时副本,然后使用LoadLibrary().

每个进程都将加载每个进程,但它们将彼此分离(因此它们将是线程安全的)。所有这些东西都可以绑定在一个包装非托管调用(LoadLibraryFreeLibraryGetProcAddress调用本身)的类中。它将使用更少的资源,并且比多个进程更快,但您必须放弃DllImport使用。

我看到的唯一好处是,这将比多个进程更好地扩展(因为它使用更少的资源),当然,如果您重用保留缓存的实例(保留进程缓存比保留对象缓存更难)。