我的Web服務有這個代碼鎖定在C#的Web服務超時時間
lock(typeof MyWebServiceClass)
那麼我所說的第三方不變的代碼,它永遠不會返回。繁榮! BAM!
我現在永久鎖定,我的網站崩潰。
這絕不會返回只發生一次在很長一段時間。
是否有可能創建超時的鎖定? IE將代碼鎖定5分鐘然後釋放鎖定?
我的Web服務有這個代碼鎖定在C#的Web服務超時時間
lock(typeof MyWebServiceClass)
那麼我所說的第三方不變的代碼,它永遠不會返回。繁榮! BAM!
我現在永久鎖定,我的網站崩潰。
這絕不會返回只發生一次在很長一段時間。
是否有可能創建超時的鎖定? IE將代碼鎖定5分鐘然後釋放鎖定?
,與其建立定時鎖,我會通過將其放入單獨的線程/任務來限制您的第三方請求。然後,啓動線程(或任務,如果.NET 4.0和TPL可用),並加入超時響應。如果加入超時,則取消線程(或在TPL任務上調用取消標記)。
是否有可能創建超時鎖?
是的,這種不愉快的情況通常被認爲是deadlock。
通常它是很好的做法,鎖定,而不是鎖定在實例字段或類本身的靜態私有對象:
private static object _syncRoot = new object();
然後:
lock(_syncRoot) {
}
看來他的問題更多是指他在鎖中執行的代碼需要非常非常長的時間,有時根本不會返回... –
@James Michael Hare,是的,如果您使用實例字段進行鎖定,則會大大增加陷入死鎖的可能性。 –
非常真實。我同意他不應該鎖定一個類型實例,也許如果我們知道更多關於他在哪裏/如何使用他的鎖,我們會知道更多,如果它是一個僵局或長期請求。無論哪種方式,他都應該按照你所說的將鎖定對象清理成一個私有實例。 –
如果第三方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在中止後通常被終止的原因。
處理此問題最安全的方法是將API調用放入單獨的進程中。您將不得不使用.NET Remoting,WCF,管道等進程間通信協議來傳輸數據到/從該調用中,這將是一個真正的難題。但是,這將是最安全的,因爲您可以安全地終止進程而不會破壞調用方的AppDomain。
我真的感覺到你,因爲這個問題很難正確解決。
5分鐘是一個很長的時間在計算機世界的鎖... –
聽起來像它卡在*致命的擁抱*(觸發恐怖音樂) –
會有什麼用?調用代碼仍然處於鎖定部分。您可以使用超時獲取鎖,並從那裏進行編碼。 –