几个AppDomains和本机代码

时间:2014-04-29 14:07:45

标签: c# .net multithreading native appdomain

我的C#应用​​程序正在使用非线程安全的本机代码。

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

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

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

2 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:4)

可以做到,但是你应该认真衡量是否可以通过福利来偿还工作。

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

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

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