2010-03-06 39 views
1

wpf對我來說很新鮮。無法在wpf UI上正確使用線程。可以幫助

我正在構建一個概念驗證應用程序,然後才能將其推廣到真正的應用程序。

場景 我應該能夠在它的中間停止處理。

工具欄2個按鈕「開始」 &「停止」

用戶按下啓動並處理長期運行的任務。 用戶決定停止任務。

我似乎無法得到正確的線程!我不能按停止,因爲它正在等待長時間運行的任務,就好像長時間運行的任務實際上在UI線程上運行一樣,而不是在後臺線程中執行。

我做錯了,你能發現它嗎?感謝您的幫助

public partial class TestView : UserControl 
{ 

    private readonly BackgroundWorker _worker; 


    public TestView 
    { 
     InitializeComponent(); 
     _worker = new BackgroundWorker(); 
     _worker.RunWorkerCompleted += RunWorkerCompleted; 
     _worker.DoWork+=DoWork; 
     _worker.WorkerReportsProgress = true; 
     _worker.ProgressChanged+=_worker_ProgressChanged; 
     _worker.WorkerSupportsCancellation = true; 
    } 


    static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Cancelled) 
     { 
      MessageBox.Show("The task has been cancelled"); 
     } 
     else if (e.Error != null) 
     { 
      MessageBox.Show("Error. Details: " + e.Error); 
     } 
     else 
     { 
      MessageBox.Show("The task has been completed. Results: " + e.Result); 
     } 
    } 
    private delegate void SimpleDelegate(); 
    void DoWork(object sender, DoWorkEventArgs e) 
    { 
     for (var i = 0; i < 1000000; i++) 
     { 
      _worker.ReportProgress(i, DateTime.Now); 
      // SimpleDelegate simpleDelegate =() => txtResult.AppendText("Test" + System.Environment.NewLine); 

      //Dispatcher.BeginInvoke(DispatcherPriority.Normal, simpleDelegate); 
     } 

     MessageBox.Show("I have done it all"); 
    } 
    private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     DateTime time = Convert.ToDateTime(e.UserState); 
     txtResult.AppendText(time.ToLongTimeString()); 
     txtResult.AppendText(Environment.NewLine); 
    } 

    private void BtnStart_Click(object sender, RoutedEventArgs e) 
    { 
     _worker.RunWorkerAsync(); 
    } 

    private void BtnStop_Click(object sender, RoutedEventArgs e) 
    { 
     _worker.CancelAsync(); 
     MessageBox.Show("Process has been stopped!"); 
    } 
} 

回答

3

您在DoWork中運行一個非常緊密的循環,並不斷地將調用的ProgressUpdates推送到主線程。這會讓它變得呆滯。

但真正的問題是,DoWork的在取消合作:

void DoWork(object sender, DoWorkEventArgs e) 
{  
    for (var i = 0; i < 1000000; i++) 
    { 
     if (_worker.CancelationPending) 
     { 
     e.Cancel = true; 
     break; // or: return to skip the messagebox 
     } 
     _worker.ReportProgress(i, DateTime.Now); 
    } 

    MessageBox.Show("I have done it all"); // remove or make depend on Cancelled 
} 
+0

嗨 感謝您的答覆。 仍然沒有工作。也沒有e.Cancelled = true。 不知道我在做什麼錯。 – user9969 2010-03-06 07:53:24

+0

錯字,應該是'e.Cancel = true'。如果您在for循環中放置'System.Threading.Thread.Sleep(10);',您的演示將會更好。 – 2010-03-06 08:07:57