2015-10-17 364 views
3

我有一種稱爲Sorter的窗體。有它的按鈕「jademy」的窗口打開「進度窗口」BackgroundWorker不會停止在CancelAsync()並且只能運行一次

private void jademy_Click(object sender, EventArgs e) 
{ 
    ProgressWindow progress = new ProgressWindow(); 
    progress.ShowDialog(); 
} 

守則「進度窗口」形式如下:

public partial class ProgressWindow : Form 
{ 
    private BackgroundWorker backgroundWorker = new BackgroundWorker(); 

    public ProgressWindow() 
    { 
     InitializeComponent(); 
     stop.Visible = true; 
     ok.Visible = false; 
     backgroundWorker.RunWorkerAsync(); 
     backgroundWorker.WorkerReportsProgress = true; 
     backgroundWorker.WorkerSupportsCancellation = true; 

     #region block1 

     backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork); 
     backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged); 
     backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted); 

     #endregion 
    } 

    private void stop_Click(object sender, EventArgs e) 
    { 
     backgroundWorker.CancelAsync(); 
    } 

    private void ok_Click(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     for (int i = 1; i <= 100; i++) 
     { 
      Thread.Sleep(100); 
      backgroundWorker.ReportProgress(i); 
     } 

    } 

    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar1.Value = e.ProgressPercentage; 
     this.Text = "Done: " + e.ProgressPercentage.ToString() + "%"; 
    } 

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if ((e.Cancelled == true)) 
     { 
      MessageBox.Show("Cancelled", "Message", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk); 
     } 

     else if (!(e.Error == null)) 
     { 
      MessageBox.Show("Error: " + e.Error.Message, "ERROR!", MessageBoxButtons.OKCancel); 
     } 
     else 
     { 
      ok.Visible = true; 
      stop.Visible = false; 
     } 
    } 
} 

現在。我有三個問題。

  1. 點擊停止按鈕什麼都不做。看起來'backgroundWorker.CancelAsync()'不會停止這個過程。

  2. 當我關閉進度窗口,我想再次運行它,我必須等待一段時間,然後點擊'jademy'按鈕。否則,進度窗口顯示如下: enter image description here(並且沒有任何更改),而不是:enter image description here它看起來像程序「記得」,即使它是ProgressWindow的新實例,也完成了工作。請注意,對於不正確的版本,「確定」按鈕可立即顯示 - 而不是等待工作完成。

  3. 我想澄清「塊1」中的代碼。說實話我完全不明白。這部分真的很重要嗎?我的意思是,我找到了很多例子(也在這個論壇上 - 例如here),其中沒有包括這部分,用戶報告說該解決方案有效。就我而言,如果沒有這個部分,進度條根本就不起作用,但也許我做錯了什麼。

+0

http://stackoverflow.com/questions/800767/how-to-kill-background-worker-completely –

+0

thread.Abort();鏈接:http://go4answers.webhost4life.com/Example/stop-background-worker-thread-while-86759.aspx –

回答

0

BackgroundWorker.CancelAsync經常被人誤解。它不會停止任何待處理的工作,但僅僅是UI線程的信號,表明工作已被取消!它只設置CancellationPending屬性,您可以定期輪詢DoWork

不幸的是,在中調用Thread.Sleep的MSDN示例非常愚蠢。通常你會在DoWork中調用阻止操作,這通常是完全與UI無關的。

查看我的回答here瞭解更多可用示例。

2
  1. 調用CancelAsync停止任何未決的工作。但是,如果工作已經開始,方法主體需要檢查是否調用了取消。見CancelAsync

CancelAsync提交終止未決的背景 操作的請求,並將CancellationPending屬性爲true。

當您調用CancelAsync時,您的工作方法有機會 停止執行並退出。 工人代碼應該定期檢查 CancellationPending屬性以查看它是否已設置爲true。

  1. 我對此一無所知。順便說一下圖片不起作用。將其嵌入到問題中。
  2. 代碼分配一個在BackgroundWorker啓動時執行的方法,並掛鉤方法來報告進度並在後臺工作完成後執行清理/更新。
+0

圖像已修復。感謝您指出。 – Piotrek