c# web服务中超时的锁
本文关键字:超时 中超 web 服务 | 更新日期: 2023-09-27 18:02:05
我的web服务有以下代码
lock(typeof MyWebServiceClass)
我调用第三方不可更改代码,它永远不会返回。繁荣!砰!
我现在永远被锁定了,我的网站崩溃了。
这个永远不会返回,只在很长一段时间内发生一次。
是否可以创建一个超时的锁?IE锁码5分钟后再解锁?
与其创建定时锁,不如将第三方请求放在单独的线程/任务中。然后,启动线程(如果. net 4.0和TPL可用,则启动任务),并超时加入响应。如果连接超时,则取消线程(或调用TPL任务上的cancel令牌)。
是否可以创建一个超时的锁?
是的,这种不愉快的情况通常被称为死锁。
通常,锁定静态私有对象而不是锁定实例字段或类本身是一种好做法:
private static object _syncRoot = new object();
然后:
lock(_syncRoot) {
}
如果第三方API有取消机制,那么就使用它。
lock(typeof MyWebServiceClass)
{
if (ThirdPartyApiThatAcceptsTimeout(TimeSpan.FromMinutes(5)))
{
// The call was successful so proceed.
}
else
{
// The call timed out so bail out.
return;
}
}
然而,我高度怀疑这个API没有取消机制,所以这就是你提出这个问题的原因。如果是这样的话,那么这就变得更加困难了。
幼稚的方法是将API调用推迟到另一个线程。如果线程没有及时响应,那么你可以中止它。lock(typeof MyWebServiceClass)
{
var thread = new Thread(
() =>
{
ThirdPartyApiThatCouldBlockIndefinitely();
});
thread.Start();
if (thread.Join(TimeSpan.FromMinutes(5))
{
// The call was successful so proceed.
}
else
{
// The call timed out so bail out.
thread.Abort();
return;
}
}
这有很多问题。首先,不能保证线程会接受中止请求。自2.0以来,CLR中有特殊的规则来规定何时可以将中止注入线程。我相信CLR会在执行非托管代码时延迟注入。因此,如果你的API是非托管的,那么中止可能无法工作。此外,中止是自愿的,因为线程可以捕获ThreadAbortException
并忽略它。其次,中止是危险的,因为中止可以被异步注入。这使得防止损坏共享状态变得非常困难。这就是AppDomain通常在abort后终止的原因。
我很同情你,因为这个问题很难正确解决。