2012-12-26 63 views
0

在下面的代碼中,當我取消註釋評論代碼時,我的程序有不正確的行爲。如何診斷爲什麼程序因`lock`語句掛起?

private void RecalculateOrders(bool force) 
    { 
     //if (force) 
     //{ 
     // lock (desiredOrdersBuy) 
     // { 
     //  RecalculateOrdersInternal(); 
     // } 
     //} 
     //else 
     //{ 
      if (Monitor.TryEnter(desiredOrdersBuy)) 
      { 
       try 
       { 
        RecalculateOrdersInternal(); 
       } 
       finally 
       { 
        Monitor.Exit(desiredOrdersBuy); 
       } 
      } 
     //} 
    } 

我不明白如何診斷究竟是什麼錯誤。我怎麼知道lock聲明如何影響我的程序?如果我有死鎖,那我該如何抓住它?你會怎麼做才能找到爲什麼lock中斷執行?

+0

你是說'Monitor.TryEnter工作,但'鎖'創建死鎖? –

+0

'Monitor.TryEnter'工作,但'鎖定'不起作用(程序行爲不正確,它掛起)我不知道這是否是死鎖,但它可能是。 – javapowered

回答

0
lock (desiredOrdersBuy) 
{ 
    RecalculateOrdersInternal(); 
} 

if (Monitor.TryEnter(desiredOrdersBuy)) 
{ 
    try 
    { 
     RecalculateOrdersInternal(); 
    } 
    finally 
    { 
     Monitor.Exit(desiredOrdersBuy); 
    } 
} 

做同樣的事情。 lock(){}是Monitor.Enter/Exit的語法糖。

你的問題是,在你評論的代碼中,你會檢查if(force)條件。

+0

我使用'Monitor.TryEnter'而不是'Monitor.Enter' – javapowered

+0

這是不正確的。鎖使用Monitor.Enter,而不是TryEnter。 – Sefe

3

好的,爲了診斷這個問題,你打算在調試時使用Threads窗口。這將允許您在正在運行的線程之間切換並查看每個線程的位置。很明顯,另一個線程對這個對象有獨佔鎖,如果你在lock語句上放置一個斷點,並在之前查看另一個Threads,我相信你會發現另一個鎖定該對象的線程。

注意:打開線程窗口您的應用程序實際上必須運行。

現在,澄清Monitor.TryEnterlock之間的差異,每MSDN DocumentationMonitor.TryEnter肯定是不同的:

如果成功,這種方法獲得的obj參數的獨佔鎖。無論鎖是否可用,此方法立即返回。

此方法與Enter類似,但不會阻塞。如果線程無法輸入,則返回false,線程不會進入關鍵部分。

所以,這就是爲什麼lock會產生死鎖,但Monitor.TryEnter不會。

+0

它真的很難調試HFT應用程序,但我可以添加「跟蹤」...可能每次我要「鎖定(desiredOrdersBuy)」我應該只是'Console.Writeln',那麼我可能會發現一個死鎖 - 鎖.... – javapowered