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

C# 如何处理阻塞同步外部DLL方法,c#,.net,com,parallel-processing,appdomain,C#,.net,Com,Parallel Processing,Appdomain,最近我使用了一个外部dll库,我对它没有任何影响。 在某些特殊情况下,此第三方dll的一个方法是阻塞且永不返回 我试图通过在新的AppDomain中执行此方法来解决此问题。在自定义超时之后,我想卸载AppDomain并杀死所有这些垃圾;) 不幸的是,它不起作用——正如有人所预料的那样 一段时间后,它抛出CannotUnloadAppDomainException,因为阻塞方法不允许正常中止线程 我依赖于使用这个库,似乎不会很快有更新 所以,即使这不是最佳实践,我也能解决这个问题吗? 任何不好的黑

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

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

不幸的是,它不起作用——正如有人所预料的那样

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

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

所以,即使这不是最佳实践,我也能解决这个问题吗?
任何不好的黑客都值得赞赏:)

您可以始终使用后台工作程序,无需创建新的appdomain。这将确保您完全控制线程的执行


但是,无法确保可以正常中止线程。由于dll是非托管的,因此很可能会导致内存泄漏。但是,生成新线程将确保应用程序不会在Dll没有响应时崩溃

阅读后(向下滚动到阻塞问题的末尾),我认为您唯一的解决方案是在不同的进程中运行该方法-这可能涉及相当多的重构和/或“主机”项目(例如控制台应用程序),该项目加载有问题的方法并使其易于调用(例如从命令行读取参数)当使用
进程

启动新进程时,AppDomain通常无法解决该问题,最好扔掉程序的状态。真正的问题是你的线程被卡住了。在这种情况下,调用Thread.Abort()不太可能工作,它也会被卡住。只有在CLR同步对象上阻塞的线程处于“可警报的等待状态”时,才能中止该线程。或者执行托管代码。处于CLR知道如何安全清理的状态。大多数第三方代码在执行非托管代码时都会像这样崩溃,无法以安全的方式清理这些代码。这种情况的一个决定性提示是AppDomain.Unload无法完成作业,它只能在中止正在域中执行代码的线程时卸载AppDomain

唯一好的替代方法是在单独的进程中运行该代码。您可以使用Process.kill()终止它。Windows进行清理。您将使用.NET互操作机制与该代码进行对话。例如命名管道、套接字、远程处理或WCF。另外,由于您现在使用未初始化的第三方代码实例重新启动,因此编写能够检测超时的代码会杀死进程、启动它并恢复内部状态,这会带来相当大的麻烦


不要忘记真正的解决办法。创建一个复制问题的小复制项目。挂起时,创建进程的小型转储。将两者发送到第三方支持小组。

为什么需要AppDomain?为什么不确定在单独的线程中运行您需要执行的任何操作?如果线程挂起,而您想要进行恶意攻击,那么使用
thread.Abort()
这是我早期的方法。但是,即使在调用Abort之后,线程也不会被终止,因此我推测我有更多的硬终止可能性AppDomains@wal中止将不起作用,在本机调用中唯一会发生的事情是,你真的不想调用它。另见。你应该考虑把线程作为僵尸留下——除非它运行很长时间,或者线程占用CPU时间,所以放弃它不会有太大的伤害。谢谢你的解释。我不想使用进程,因为它是一个可以部署到多个服务器的ASP.NET应用程序。所以我不得不为权利而争论。此外,我必须多次调用此外部方法,并将其托管在单独的进程中肯定不会提高性能,因为它已经没有我希望的那么快了。无论如何,这似乎是唯一的解决办法(我能做到),所以我可以试试。谢谢你的帮助!