2013-02-27 96 views
0

我有一個程序有時運行速度非常慢。TryTake阻止收集性能

我試圖Teleriks Justtrace找出,什麼可能會導致應用程序的掛起。

非UI線程(因此我相信這不是真正的掛起的原因)assync。獲取對象(Enqueue workitems)並將其引入一些工作。

排隊:

public void EnqueueObject(WorkUnit workunit) 
     { 
      try 
      { 
       workUnits.Add(workunit); 
      } 
      catch (Exception ex) 
      { 
       /handle exception 
      } 
     } 

出列:

public WorkUnit Dequeue() 
     { 
      try 
      { 
       WorkUnit aWorkUnit = null; 
       workUnits.TryTake(out aWorkUnit, 1000); 

       return aWorkUnit ; 
      } 
      catch (InvalidOperationException ex) 
      { 
       // 

      } 
        return null; 
     } 

TryTake被用來檢查當前工作(而不是調用時剛剛拋出一些錯誤BlockingCollection Complete方法的中止 - 這不是我不希望使用錯誤進行編程流程)

致電請求退出:

while(!isStopped) 
{ 
    ProcessWorkItem(Dequeue()); 
} 

到這裏看起來很簡單。

問題是,Teleriks JustTrace顯示,行「workUnits.TryTake(out aWorkUnit,1000);」佔該程序總執行時間的30%。

這怎麼可能?

有了更多的細節,它顯示了TryTake System.Threading.Monitor.Wait內部一直佔用 - 我認爲Wait會發送一個線程進入睡眠狀態,所以它在等待期間不消耗任何東西。思想中的錯誤在哪裏?

+0

應該沒問題。但是你是否將大量項目添加到隊列中?還是每次都真的等待一秒?順便說一下,如果您使用BlockingCollection.CompleteAdding()會導致錯誤,那麼您一定是做錯了! – 2013-02-27 11:06:17

+0

你有沒有試過讓'TryTake'等待一個元素的使用?代碼:'workUnits.TryTake(out aWorkUnit,-1);'。 – Dzienny 2013-02-27 11:25:11

+0

@MatthewWatson如果你在一個循環中有一個Take(),然後使用CompleteAdding(),Take()將會拋出一個InvalidOperationException異常。 (請參閱http://msdn.microsoft.com/en-us/library/dd997371.aspx)。這裏不需要例外。金額取決於。我試圖添加3000個項目到隊列中。 – Offler 2013-02-27 12:19:52

回答

0

您可以嘗試使用workUnits.TryTake(out aWorkUnit)而不使用超時參數。然後,你應該修改while循環,類似於此:

while(!isStopped) 
{ 
    WorkUnit wu = Dequeue(); 
    if(wu != null) 
     ProcessWorkItem(wu); 
    else 
     Thread.Sleep(40); 
} 

此外,如果你正在運行的UI這段代碼線程它會使你的UI響應。您應該使用例如BackgroundWorker進行操作。下面是BackgroundWorker類的從MSDN文檔的描述:

BackgroundWorker的類允許您在一個單獨的專用線程上運行操作。諸如下載和數據庫事務等耗時的操作可能會導致您的用戶界面(UI)看起來好像在運行時停止響應一樣。如果您想要一個響應式用戶界面,並且您面臨着與此類操作相關的長時間延遲,則BackgroundWorker類提供了一個便捷的解決方案。

+0

發生以下情況:發生以下情況:程序總計算時間爲100 ms,TryTake顯示爲18 ms(〜20%),即使程序運行幾分鐘,百分比也會保持穩定。 (例如,如果它運行5分鐘,則顯示1.182計算時間,並且其中234是TryTake) – Offler 2013-02-27 14:12:00

+0

@Offler它不在UI線程上運行正確嗎? – Dzienny 2013-02-27 14:26:04

+0

是的,它運行在另一個線程 - 這就是爲什麼我大多認爲這不應該導致掛起。我只是好奇爲什麼telerik跟蹤工具顯示這是大多數CPU使用情況的項目。有20%的負載只是一個採取操作(獨立和其他需要或不需要)似乎太高 – Offler 2013-02-28 07:14:59