IIS应用程序池回收和本机程序集

时间:2014-10-07 06:06:27

标签: c# .net iis .net-assembly

我有一个在IIS下运行的应用程序,该应用程序有三个程序集:托管程序集,混合程序集和本机DLL。 托管程序集公开单个对象MaS,它通过混合单例NaS(C ++ / CLI)包装本机单MiS

问题

当IIS回收应用程序池时,托管单例MaS似乎消失,其程序集从APPDOMAIN卸载,混合的MiS也是如此。但是,原生单身NaS会粘在一起并且不会被破坏。这在我的情况下是有问题的,因为当应用程序被再循环并再次加载时,托管单例,现在MaS1变得混乱,因为它在内存中找到已经存在的本机单例NaS

问题

如何在应用程序池回收处理本机dll?他们被卸下了吗?

1 个答案:

答案 0 :(得分:1)

Appdomain回收不会卸载appdomain,它会加载新域,后续请求将由新的appdomain处理。

旧的appdomain仅在处理完已处理的请求时卸载。

如果旧的appdomain在非托管代码中执行阻塞操作,也可能无法卸载。

作为一种解决方法,您可以禁用apppool recycle并配置ovelapping worker进程。 单独的工作进程肯定会隔离非托管dll状态。

您可以使用以下代码轻松检查非托管dll是否在appdomains之间共享状态:

托管代码:

[DllImport("Win32Library.dll")]
public static extern Int16 inc();

private readonly static DateTime AppDomainStarted = DateTime.UtcNow;

public ActionResult Counter()
{
    return new JsonResult { Data = new { counter = inc(), appDomainId = AppDomain.CurrentDomain.Id, started = AppDomainStarted.ToString() }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}

非托管代码:

extern "C" __declspec(dllexport) short inc();

short inc()
{
    static int counter = 0;
    return counter++;
}

只需重新编译您的aspnet代码并刷新浏览器以查看计数器中的递增结果,以及工作进程中的appdomain id。确保使用IISExpress进行调试。