簡體   English   中英

檢測死鎖WinForms應用程序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM