我有一个可以有多个应用程序域的进程。每个AppDomain 都会收集一些统计数据。在指定的时间之后,我想累积这些统计数据并将它们保存到文件中。
实现此目的的一种方法是远程处理,我想避免这种情况。
我想到的唯一其他技术是将每个应用程序域的数据保存在一个文件中,并且在特定时间之后,其中一个应用程序域收集所有数据并累积它们。
但如果这一切都可以在内存中完成,而不需要序列化信息以在 AppDomain 之间传递,那就太理想了。有人有主意吗?
可以在 AppDomain 之间共享数据,而无需花费编组成本。但这是一种相当hacky的方式。您可以创建一个在所有 AppDomain 之间通过引用共享的源数据对象。通过这种方式,您可以将所有数据放入一个共享对象中,而无需花费编组成本。听起来太容易了,难以置信?
首先要知道如何在不进行编组的情况下在 AppDomain 之间共享数据。为此,您可以通过 Marshal.UnsafeAddrOfPinnedArrayElement 获取数据源对象的对象地址。然后将此 IntPtr 传递给所有对此感兴趣的 AppDomain。在目标 AppDomain 中,您需要将此 IntPtr 强制转换回对象引用,这可以通过 JIT::CastAny 完成,如果您从方法返回一个对象并将其指针压入堆栈,则可以完成此操作。
Viola,您在 AppDomain 之间共享一个对象作为普通指针,并且您收到 InvalidCastExceptions。问题是您必须为所有 AppDomain 设置 LoaderOptimization.MultiDomain,以确保定义共享数据类型的程序集作为 AppDomain 中性类型加载,该类型在所有 AppDomain 之间具有相同的方法表指针。
您可以找到一个示例应用程序,它作为 WMemoryProfiler 的一部分执行此操作。请参阅此链接了解更多信息详细说明和下载链接 http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx到示例代码。
基本代码是
[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);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)