c# - 在 AppDomain 之间共享数据

标签 c# appdomain

我有一个可以有多个 AppDomain 的进程。每个 AppDomain 收集一些统计信息。在指定的时间后,我想累积这些统计数据并将它们保存到一个文件中。

实现此目的的一种方法是远程处理,我想避免这种方法。

我唯一想到的其他技术是将每个 AppDomain 的数据保存在一个文件中,并且在特定时间后,其中一个 AppDomain 收集所有数据并累积它们。

但如果这一切都可以在内存中完成,而不需要序列化信息以在 AppDomain 之间传递,那将是理想的。有人有什么想法吗?

最佳答案

可以在 AppDomain 之间共享数据而无需 Marshalling 成本。但这是一种相当hacky的方式。您可以创建一个源数据对象,该对象通过引用在所有 AppDomain 之间共享。通过这种方式,您可以将所有数据放入一个共享对象中,而无需编码成本。听起来太容易了?

首先要知道如何在没有编码的情况下在 AppDomain 之间共享数据。为此,您可以通过 Marshal.UnsafeAddrOfPinnedArrayElement 获取数据源对象的对象地址。然后将此 IntPtr 传递给对此感兴趣的所有 AppDomain。在目标 AppDomain 中,您需要将此 IntPtr 转换回对象引用,这可以通过 JIT::CastAny 完成,如果您从方法返回对象并将其指针压入堆栈,则可以完成此操作。

Viola,您在 AppDomains 之间共享了一个对象作为普通指针,您得到了 InvalidCastExceptions。问题是您必须为所有 AppDomain 设置 LoaderOptimization.MultiDomain 以确保定义共享数据类型的程序集加载为 AppDomain 中性类型,该类型在所有 AppDomain 之间具有相同的方法表指针。

作为 WMemoryProfiler 的一部分,您可以找到一个示例应用程序来执行此操作。查看此链接了解更多 detailed explanation and download link到示例代码。

基本代码是

[LoaderOptimization(LoaderOptimization.MultiDomain)]
static public void Main(string[] args)
{

    // To load our assembly appdomain neutral we need to use MultiDomain on our hosting and child domain
    // If not we would get different Method tables for the same types which would result in InvalidCastExceptions
    // for the same type.
    var other = AppDomain.CreateDomain("Test"+i.ToString(), AppDomain.CurrentDomain.Evidence, new AppDomainSetup
        {
            LoaderOptimization = LoaderOptimization.MultiDomain,
        });

    // Create gate object in other appdomain
    DomainGate gate = (DomainGate)other.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DomainGate).FullName);

    // now lets create some data
    CrossDomainData data = new CrossDomainData();
    data.Input = Enumerable.Range(0, 10).ToList();

    // process it in other AppDomain
    DomainGate.Send(gate, data);

    // Display result calculated in other AppDomain
    Console.WriteLine("Calculation in other AppDomain got: {0}", data.Aggregate);
    }
}

关于c# - 在 AppDomain 之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2206961/

相关文章:

c# - 在 System.Security.Cryptography 中找不到 `DataProtectionScope` 和 `ProtectedData` 类

c# - 动态创建用于从 Entity Framework 获取数据的表达式查询

c# - 如何将构造函数参数传递给 AppDomain.CreateInstanceXXX?

c# - 如何跨 AppDomain 将引用作为方法参数传递?

c# - C# 应用程序中的多个 VB6 单元

c# - 如何使用 C# 正确卸载 AppDomain?

c# - 求解复杂的 ODE 集

c# - 发布 Azure Webjob 时缺少程序集 CS0234 WebJobs、CS0246 QueueTriggerAttributes

c# - Windows 7 开始菜单搜索的自定义源

c# - 注销租约抛出 InvalidOperationException