我有一个在IIS下运行的应用程序,该应用程序有三个程序集:托管程序集,混合程序集和本机DLL。
托管程序集公开单个对象MaS
,它通过混合单例NaS
(C ++ / CLI)包装本机单MiS
。
问题
当IIS回收应用程序池时,托管单例MaS
似乎消失,其程序集从APPDOMAIN卸载,混合的MiS
也是如此。但是,原生单身NaS
会粘在一起并且不会被破坏。这在我的情况下是有问题的,因为当应用程序被再循环并再次加载时,托管单例,现在MaS1
变得混乱,因为它在内存中找到已经存在的本机单例NaS
。
问题
如何在应用程序池回收处理本机dll?他们被卸下了吗?
答案 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进行调试。