zoukankan      html  css  js  c++  java
  • Error while unloading appdomain. (Exception from HRESULT: 0x80131015)

    消息中间件以不同AppDomain方式隔离加载消息处理器。其中的AppDomainWatcher类型会监控每个插件目录的文件是否变化,当发生变化时则卸载这个AppDomain,并在下次访问时新建。开发进度下,往往会频繁更新这些插件。极为偶然的情况下会出现:Attempted to access an unloaded AppDomain.   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName) 。WinDbg附加等待错误发生,之后捕捉到一个second chance。大致内容如下:

     1 ModLoad: 000007fe`e9290000 000007fe`e937a000   C:\Windows\Microsoft.NET\Framework64\v4.0.30319\diasymreader.dll
     2 System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>xxxxxx.exe</AppDomain><Exception><ExceptionType>System.CannotUnloadAppDomainException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Error while unloading appdomain. (Exception from HRESULT: 0x80131015)</Message><StackTrace>   at System.AppDomain.Unload(AppDomain domain)
     3    at xxxxxx.Messaging.Configuration.AppDomainPool.AppDomainWatcher.fileSystemWatcher_Changed(Object sender, FileSystemEventArgs e)
     4    at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
     5    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)</StackTrace><ExceptionString>System.CannotUnloadAppDomainException: Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
     6    at System.AppDomain.Unload(AppDomain domain)
     7    at xxxxxx.Messaging.Configuration.AppDomainPool.AppDomainWatcher.fileSystemWatcher_Changed(Object sender, FileSystemEventArgs e)
     8    at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
     9    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)</ExceptionString></Exception></TraceRecord>
    10 (119c.1358): CLR exception - code e0434352 (!!! second chance !!!)
    11 KERNELBASE!RaiseException+0x39:
    12 000007fe`fdaea49d 4881c4c8000000  add     rsp,0C8h

    AppDomainWatcher产生异常的源代码部分:

     1 /// <summary>
     2 /// 文件系统变化
     3 /// </summary>
     4 /// <param name="sender">发送方</param>
     5 /// <param name="e">事件参数</param>
     6 private void fileSystemWatcher_Changed(Object sender, FileSystemEventArgs e)
     7 {
     8   m_fileSystemWatcher.EnableRaisingEvents = false;
     9    m_fileSystemWatcher.Changed -= new FileSystemEventHandler(fileSystemWatcher_Changed);
    10    m_fileSystemWatcher.Dispose();
    11 
    12    lock (this.SyncRoot)
    13    {
    14      AppDomain.Unload(this.AppDomain);
    15    }
    16 
    17    OnDomainUnload(EventArgs.Empty);
    18 }

    在卸载一个AppDomain时抛出了System.CannotUnloadAppDomainException,导致卸载该AppDomain失败。查阅MSDN关于AppDomain.Unload函数Remarks:

    The dedicated thread attempts to unload the domain, and all threads in the domain are aborted. If a thread does not abort, for example because it is executing unmanaged code, or because it is executing a finally block, then after a period of time a CannotUnloadAppDomainException is thrown in the thread that originally called Unload. If the thread that could not be aborted eventually ends, the target domain is not unloaded

    用~* k、~* e !clrstack查看所有线程的call stack,发现有一处停留在获取数据库连接的等待中,这就是AppDomain卸载失败的原因。再看一段MSDN关于AppDomain卸载的补充:

    By the way, when a thread calls AppDomain.Unload, the CLR waits 10 seconds (by default) for the threads in the unloading AppDomain to leave it. If after 10 seconds, the thread that called AppDomain.Unload doesn’t return, it will throw a CannotUnloadAppDomainException, and the AppDomain may or may not be unloaded in the future.
    
    Note If a thread calling AppDomain.Unload is in the AppDomain being unloaded, the CLR creates another thread, and this new thread attempts to unload the AppDomain. The first thread will forcibly throw the ThreadAbortException and unwind. The new thread will waitfor the AppDomain to unload, and then the new thread terminates. If the AppDomain fails to unload, the new thread will process a CannotUnloadAppDomainException, but since you did not write the code that this new thread executes, you can’t catch this exception.

    默认情况下CLR会等待10秒由所有线程退出,之后调用卸载线程没有返回则抛出CannotUnloadAppDomainException。对于在被卸载AppDomain中的线程尝试卸载,CLR会新建一个线程处理。

  • 相关阅读:
    找控件的父类
    silverlight和wpf中暴露 给子类override
    Oracle PLSQL 记录
    C#之TopShelf启动Windows服务 原文链接:https://blog.csdn.net/qq_36664495/java/article/details/90600995
    Super socket 记录知识
    oracle 查找字符位置 开始按照长度截取
    转 acl 库是啥、主要包含哪些功
    转自 posted on 2015-05-18 11:50 LitDev https://www.cnblogs.com/New-world/p/4511543.html
    dtu server 编译错误
    iOS 杂笔-22(万年一遇~一张图片对代理的理解)
  • 原文地址:https://www.cnblogs.com/junchu25/p/2637276.html
Copyright © 2011-2022 走看看