c# - 如何处理第三方代码中的死锁
问题描述
我们有一个第三方方法Foo
,它有时会因为未知原因而陷入死锁。
我们正在执行一个单线程 tcp-server 并每 30 秒调用一次此方法以检查外部系统是否可用。
为了缓解第三方代码中的死锁问题,我们将 ping-call 放在了Task.Run
to 中,这样服务器就不会死锁。
喜欢
async Task<bool> WrappedFoo()
{
var timeout = 10000;
var task = Task.Run(() => ThirdPartyCode.Foo());
var delay = Task.Delay(timeout);
if (delay == await Task.WhenAny(delay, task ))
{
return false;
}
else
{
return await task ;
}
}
但这(在我们看来)有可能使自由线程的应用程序匮乏。因为如果一次调用ThirdPartyCode.Foo
死锁,线程将永远无法从这个死锁中恢复,如果这种情况经常发生,我们可能会耗尽资源。
是否有一种通用方法应该如何处理死锁的第三方代码?
ACancellationToken
不起作用,因为第三方 api 不提供任何取消选项。
更新: 手头的方法是从 SAP 提供的 SAPNCO.dll 中建立和测试到 sap 系统的 rfc 连接,因此该方法不是简单的网络 ping。我重命名了问题中的方法以避免进一步的误解
解决方案
是否有一种通用方法应该如何处理死锁的第三方代码?
是的,但这并不容易或简单。
行为不端的代码的问题在于它不仅会泄漏资源(例如,线程),而且还可以无限期地持有重要资源(例如,一些内部“句柄”或“锁”)。
强制回收线程和其他资源的唯一方法是结束进程。该操作系统用于清理行为不端的进程,并且非常擅长。因此,这里的解决方案是启动一个子进程来进行 API 调用。您的主应用程序可以通过重定向 stdin/stdout 与其子进程通信,如果子进程超时,主应用程序可以终止它并重新启动它。
不幸的是,这是取消不可取消代码的唯一可靠方法。
推荐阅读
- azure - 从 azure-aks pod 调用具有不同源 IP 地址的外部服务
- apache-spark - spark s3n 支持端点是否类似于 s3a
- javascript - 嵌套数组 - 跟踪数组内对象的位置
- sql - 键和值的 SQL 查询
- java - 根据条件将字符串转换为字符串
- qt - 未显示 Combobox 的完成符
- mongodb - 如何在 go(lang) 中连接到 mlab mongodb 数据库?
- c# - C# JsonConvert - 如何解析不规则的键/值 JSON?
- swift - 如何在 Swift Playgrounds 中获得弹出对话框
- php - 如何合并jpeg图像