2011-06-24 244 views
2

我有這樣的代碼暫停和恢復線程:暫停和恢復線程

public partial class frmMain : Form 
    { 
     (...)   
     ManualResetEvent wait_handle = new ManualResetEvent(true); 
     (...) 
    } 

private void frmMain_Shown(object sender, EventArgs e) 
    {      
      ThreadPool.QueueUserWorkItem(new WaitCallback(TheLoop)); 
    } 

private void TheLoop(object stateinfo) 
     { 
      bool hasInfo = true; 
      while (doLoop) 
      { 
       wait_handle.WaitOne(); 

       bool hasLines = GetInfo(); 
       if (hasLines) 
       { 
        //Consuming time Operation 1 
        System.Threading.Thread.Sleep(7000); 
        if (CurrentLine < line.Count - 1) 
         CurrentLine++; 
        else 
        {             
         bool hasInfo2 = GetInfo2(); 
         if (hasInfo2) 
         {        
          //Consuming time Operation 2 
          System.Threading.Thread.Sleep(7000); 
         } 


         CurrentLine = 0; 
        } 
       } 
       else 
        System.Threading.Thread.Sleep(40000); //Wait to query again 
      } 
     } 

private void btnPauseResume_Click(object sender, EventArgs e) 
     { 
      if (btnPauseResume.Text == "Pause") 
      { 
       btnPauseResume.Text = "Resume"; 
       wait_handle.Reset(); 
      } 
      else 
      { 
       btnPauseResume.Text = "Pause"; 
       wait_handle.Set(); 
      } 
     } 

上面的代碼顯示了一個週期的信息,它的工作原理髮現暫停和恢復「第一耗時操作」,但沒有按如果我在第二個消費時間操作中按下按鈕暫停線程,則這個繼續,當第一個再次出現時,它會在那裏暫停。

我在這裏錯過了什麼? Thx

+0

更完整的代碼可能會有所幫助。 – CrazyDart

+0

感謝編輯CrazyDart,我讀了多個wait_handle.WaitOne();每次我需要暫停或恢復一個線程時都需要,我試圖在Operation 2之前添加一個,但沒有工作。 – Somebody

+0

在消費時間操作中,我從數據庫中讀取並使用調用在GUI中設置值。這就是全部,所以我不認爲這會成爲問題。 – Somebody

回答

0

明白了吧!事情就是你把WaitOne()放在哪裏。舉例來說,如果我有一個While循環(就像我的例子),如果我把它放在它之前,無論我多少次點擊暫停按鈕,它都不會停止線程,因爲循環已經開始,所以它是邏輯的,但是如果我把它放在最後,那麼它就會起作用。

讚賞你的幫助。

0

我從來沒有見過有人暫停一個線程。在單獨的威脅上執行的類或方法內部創建委託和事件。每當你想暫停你的時候,執行那個事件。

+0

你好Tono,但你意識到我可以暫停並恢復與右上方的代碼線程?我唯一的問題是能夠在第二次操作中暫停線程。 – Somebody

1

您是否考慮過使用Background Worker而不是因爲您使用的是WinForms?這可能比嘗試「暫停」一個線程更容易。您可以檢查CancellationPending屬性以查看用戶是否選擇取消操作。該鏈接有一個很好的示例。

+0

感謝您回覆ZeroVector,但是我並沒有在項目開始時考慮Background Worker,現在項目非常龐大,我不想再次改變整個事情。所以我必須繼續嘗試暫停第二個操作。 – Somebody

0

如果放置在第二次耗時操作之前,沒有任何理由可以阻止第二次致電WaitOne工作。由於您使用的是ManualResetEvent,所以等待句柄的狀態將一直存在,直到調用SetReset。這意味着如果您通過撥打Set來恢復線索,則兩個電話WaitOne都會通過。同樣,如果您通過調用Reset暫停該線程,則兩個對WaitOne的調用都將被阻止。當然,如果有多於一個的WaitOne調用,將無法預測工作線程將暫停的位置。

+0

是的,所以當按下按鈕時,他們應該暫停兩個操作,如果繼續,則繼續,但在第二個操作之前添加第二個「waitOne」時不起作用,可能需要再次檢查。感謝Brian – Somebody