C# 几个AppDomains和本机代码

C# 几个AppDomains和本机代码,c#,.net,multithreading,native,appdomain,C#,.net,Multithreading,Native,Appdomain,我的C#应用程序使用的本机代码不是线程安全的 我可以运行该本地代码的多个进程,使用进程间通信来实现并发性 我的问题是,我是否可以改为使用应用程序域,以便多个托管线程(每个线程位于不同的应用程序域上)调用本机代码,并且它们不会相互干扰 主要目标是防止进程分离。不,AppDomains是一个纯托管代码概念。它通过保持托管对象根的分离来实现隔离。一个AppDomain无法看到另一个AppDomain的对象,这使得中止代码和卸载程序集非常安全。它从不意外地丢弃可能包含状态的所有数据 非托管代码对GC堆和

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

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

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


主要目标是防止进程分离。

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

非托管代码对GC堆和AppDomains是完全不可知的,它将在其数据部分和自己的本机堆(HeapAlloc)中进行分配。这种分配是全球性的。如果将进程作为隔离边界,则需要一个辅助进程来加载DLL,并使用.NET进程互操作机制(套接字、命名管道、内存映射文件、远程处理、WCF)与之通信


从技术上讲,您可以创建DLL的副本,每个副本都有不同的名称。但这一功能的伸缩性非常差,pinvoke非常笨拙,因为你不能再使用[DllImport]。每个导出函数和LoadLibrary()和GetProcAddress()都需要一个委托声明来初始化委托对象。

是的这是可以做到的,但您应该认真衡量工作是否得到了回报

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

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


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

回答得很好。是否有其他方法来运行相同的本机代码,以避免静态数据发生冲突?(多个流程除外)