2010-03-06 41 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