如何处理阻塞同步外部DLL方法

das*_*dot 2 .net c# com parallel-processing appdomain

最近我使用外部DLL库,我对它没有任何影响.在某些特殊情况下,此第三方dll的方法是阻塞并且永不返回.

我试图通过在新的AppDomain中执行此方法来解决此问题.在自定义超时后,我想卸载AppDomain并杀死所有这些垃圾;)

不幸的是,它不起作用 - 正如有人所期望的那样.

一段时间后,它会抛出CannotUnloadAppDomainException,因为阻塞方法不允许正常中止线程.

我依赖于使用这个库,似乎不会很快有更新.

那么我可以解决这个问题,即使这不是最佳做法吗?任何糟糕的黑客赞赏:)

Han*_*ant 5

AppDomain通常无法解决该问题,最好不要丢弃程序的状态.真正的问题是你的线程被卡住了.在这种情况下,调用Thread.Abort()不太可能工作,它也会被卡住.如果线程是"可警告的等待状态",则只能在CLR同步对象上阻塞线程.或者执行托管代码.在CLR知道如何安全清理的状态下.在执行非托管代码时,大多数第三方代码都会像这样崩溃,无法以安全的方式清理它.这种情况的决定性暗示是AppDomain.Unload无法完成工作,它只能卸载AppDomain,因为它可以中止正在域中执行代码的线程.

唯一不错的选择是在单独的进程中运行该代码.你可以使用Process.Kill()杀死它.Windows进行清理.您将使用.NET互操作机制与该代码进行通信.像命名管道,套接字,远程处理或WCF.另外,处理编写可以检测超时的代码的麻烦会导致进程崩溃,启动备份并恢复内部状态,因为您现在使用该第三方代码的未初始化实例重新启动.

不要忘记真正的修复.创建一个可以重现问题的小型repro项目.当它挂起时,创建一个进程的minidump.将两者发送给第三方支持小组.