我对我正在处理的一些代码有一个不寻常的要求。我正在使用不可靠的第三方库进行一些条形码扫描(它在运行太多次后停止工作)。为了解决这个问题,我决定在单独的AppDomain中完成工作,然后在完成后卸载AppDomain。这是我正在做的事情的简单但准确的图片:
string domainID = Guid.NewGuid().ToString();
AppDomainSetup setup = new AppDomainSetup();
AppDomain domain = AppDomain.CreateDomain(domainID, null, setup);
string result = null;
try
{
domain.SetData("stream", stream);
domain.DoCallBack(ScanningContext.DoWork);
result = domain.GetData("result") as string;
}
finally
{
AppDomain.Unload(domain);
}
return result;
public static void DoWork()
{
Stream s = AppDomain.CurrentDomain.GetData("stream") as Stream;
ObjectHandle handle = AppDomain.CurrentDomain.CreateInstance("Scanning",
"Scanner");
Scanning.Scanner scanner = (Scanning.Scanner)handle.Unwrap();
Scanning.Result[] results = scanner.Scan(s);
AppDomain.CurrentDomain.SetData("result", results[0].Text);
}
“Scanner”是我正在使用的库周围的包装类。它位于“扫描”组件中;一个单独的项目,仅用于此目的。
ScanningContext.DoWork是一个静态方法,位于我的服务程序集中。
我的问题是这个方法存在内存泄漏问题。内存不断增长和增长(当然,当调用此代码时),直到抛出OutOfMemoryExceptions。
我找不到泄漏的地方。我的所有溪流都被处理掉了。我的所有字节数组都被清空了。我正在清理列表,过去对我有用的一切。我大约90%确信泄漏与这个AppDomain的东西有关。这是我第一次使用它,所以我可能做错了。
我对AppDomains之外的另一种方法持开放态度。我确实需要能够从“扫描仪”类返回结果,因此不能选择产生一个过程。
答案 0 :(得分:2)
AppDomain.Unload方法启动一个单独的线程来卸载域,这可能由于各种原因而失败(执行非托管代码的线程是个问题)。下面是一个示例代码,用于检查应用程序域是否已卸载(取自msdn docs):
try
{
Console.WriteLine();
// Note that the following statement creates an exception because the domain no longer exists.
Console.WriteLine("child domain: " + domain.FriendlyName);
}
catch (AppDomainUnloadedException e)
{
Console.WriteLine("The appdomain MyDomain does not exist.");
}