无法在wpf UI上获取线程

时间:2010-03-06 07:30:36

标签: wpf

我正在构建一个概念验证应用程序,然后才能推出真实应用程序。

情景 我应该可以在它的中间停止处理。

工具栏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!");
    }
}

1 个答案:

答案 0 :(得分:3)

您在DoWork内部运行一个非常紧密的循环,并不断将Invoked 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
}