【发布时间】:2021-03-30 08:35:14
【问题描述】:
我们有一个第三方方法Foo,它有时会因为未知原因而陷入死锁。
我们正在执行一个单线程的 tcp-server,每 30 秒调用一次这个方法来检查外部系统是否可用。
为了缓解第三方代码中的死锁问题,我们将 ping 调用放在 Task.Run 中,以便服务器不会死锁。
喜欢
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 死锁,线程将永远无法从死锁中恢复,如果这种情况经常发生,我们可能会耗尽资源。
是否有一种处理死锁第三方代码的通用方法?
CancellationToken 不起作用,因为第三方 api 不提供任何取消选项。
更新: 手头的方法是从 SAP 提供的 SAPNCO.dll 中建立和测试到 sap-system 的 rfc-connections,因此该方法不是简单的 network-ping。为了避免进一步的误解,我重命名了问题中的方法
【问题讨论】:
-
将 CancellationToken 与 Task.Run 一起使用
-
让第 3 方修复他们的产品……但我猜你“现在”需要一些东西……
-
什么是
ThirdPartyCode?是图书馆吗?我想您可以尝试将其加载到separate domain,如果它停止,请重新加载。 -
“是否有一个通用的方法应该如何处理死锁的第三方代码?” - 是的,停止付款,停止使用他们的产品!
-
所以,它是 SAP。您的公司可能会在支持计划上花一大笔钱。使用它。