2011-10-14 54 views
1

我無法取消其中包含Thread.Sleep(100)的後臺工作人員。如何取消睡眠後臺工作人員?

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
{ 
     int count; 
     try 
     { 
      count = int.Parse(textBox3.Text); 

      for (int i = 0; i < count; i++) 
      { 
       backgroundWorker1.ReportProgress((int)(((double)(i + 1)/count) * 1000)); 
       //Computation code 
       Thread.Sleep(int.Parse(textBox4.Text)); 
      } 
     } 
     catch (Exception ex) 
     { 
      request.DownloadData(url); 
      MessageBox.Show(ex.Message); 
     } 
} 

private void cancel_Click(object sender, EventArgs e) 
{ 
    backgroundWorker1.CancelAsync(); 
    progressBar1.Value = 0; 
} 

如果我刪除Thread.Sleep(100),則取消的作品,但否則它只是不斷去(進度條不停止)。

編輯:添加代碼

+1

你可以發佈循環的其餘部分嗎?它是否在每次迭代時檢查一些標誌?減少睡眠時間,對1說解決問題?睡眠(100)在處理循環中的 – Joey

+0

? – Reniuz

+1

不完整的代碼。只有睡眠(100)電話只能_delay_取消一點點。必須有別的東西。 –

回答

6

當你調用CancelAsync它只是設置一個名爲CancellationPending到真正的財產。現在你的背景工作者可以而且應該定期檢查這個標誌是否爲真,以優雅地完成其操作。所以你需要將你的後臺任務分成幾部分,你可以檢查取消。

private void DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     while(true) 
     { 
      if(worker.CancellationPending) 
      { 
       e.Cancel = true; 
       return; 
      } 

      Thread.Sleep(100); 
     } 
    } 
+1

+1但是,這並不能解釋它是如何在沒有Thread.Sleep的情況下工作的。 – Joey

+0

@Joey - 當然是的。我們不知道循環實際上在做什麼。 –

+0

這是有效的,你知道它爲什麼不工作嗎? – Jack

0

使用了Thread.interrupt的其餘部分,當你要取消的後臺線程從WaitSleepJoin狀態退出。

http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt.aspx

+2

我認爲如果存在更優雅的方式(即使用worker.CacellationPending),則中斷線程是一件壞事。 – Joey

+0

Thread.Interrupt只是當你想取消時退出睡眠狀態。之後,您捕獲ThreadInterruptedException並檢查CancellationPending。 – mircea

+0

我寧願讓睡眠時間更短,所以你不必擔心捕捉一個'ThreadInterruptedException'。 – Joey