[英]Detecting deadlocks WinForms application
我們有一個很大的winforms桌面應用程序。 我們的應用程序偶爾會陷入僵局,我們不確定這是怎么發生的。
我們確實知道這是由鎖定操作引起的。 因此,我們有很多這樣的代碼部分:
lock (_someObj)
DoThreadSaveOperation();
我們能夠檢測到死鎖是由我們想要將所有這些鎖操作轉換為如下所示的方法:
bool lockTaken = false;
var temp = _someObj;
try {
System.Threading.Monitor.TryEnter(temp, 1000, ref lockTaken);
if (!lockTaken)
{
// log "can't get lock, maybe deadlock, print stacktrace
}
DoThreadSaveOperation();
}
finally {
System.Threading.Monitor.Exit(temp);
}
此“鎖定服務”應處於中心位置。 問題在於它必須像這樣被調用:
LockService.RunWithLock(object objToLock, Action methodToRun);
這意味着我們必須為鎖后執行的每個語句創建一個委托函數。
由於這將需要大量重構,所以我想如果你們對此有更好/更好的主意並且也征求您的意見,我想嘗試一下stackoverflow。
謝謝您的幫助=)
由於現有的lock
功能緊密地模擬了using
語句,因此建議您將邏輯包裝在實現IDisposable的類中。
該類的構造函數將嘗試獲取該鎖,如果無法獲取該鎖,則可以引發異常或將其記錄下來。 Dispose()方法將釋放鎖定。
您可以在using
語句中使用它,因此在遇到異常時它將很健壯。
所以像這樣:
public sealed class Locker: IDisposable
{
readonly object _lockObject;
readonly bool _wasLockAcquired;
public Locker(object lockObject, TimeSpan timeout)
{
_lockObject = lockObject;
Monitor.TryEnter(_lockObject, timeout, ref _wasLockAcquired);
// Throw if lock wasn't acquired?
}
public bool WasLockAquired
{
get
{
return _wasLockAcquired;
}
}
public void Dispose()
{
if (_wasLockAcquired)
Monitor.Exit(_lockObject);
}
}
您可以這樣使用:
using (var locker = new Locker(someObj, TimeSpan.FromSeconds(1)))
{
if (locker.WasLockAquired)
{
// ...
}
}
我認為這將有助於最大程度地減少代碼更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.