将结果从已取消的BackgroundWorker线程传回主线程

时间:2014-01-10 23:38:49

标签: c# multithreading backgroundworker

如何取消后台作业并传回错误讯息。我知道你可以使用DoWorkEventArgs e.Results将结果传回主线程,但是当取消子线程时,e.Results会被覆盖。例如:

private MyProgram_DoWork(object sender, DoWorkEventArgs e)
{
     e.Cancel = true;
     e.Result = "my error message";
     return;
}

private void MyProgram_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
     if ((e.Cancelled == true))
     { 
            string ErrorMsg = (string)e.Result;   //exception happens here 

            ....
     }
     else
     { 
          // success code
     }
}

是否有另一种方法可以阻止我的子线程并将字符串发送回主线程?

1 个答案:

答案 0 :(得分:1)

如果你的长期运行过程被取消,它就不会有“结果”,因为这个过程没有完全结束。

根据documentation

  

在访问Result属性之前,RunWorkerCompleted事件处理程序应始终检查Error和Cancelled属性。如果引发了异常或操作被取消,则访问Result属性会引发异常。

我在BackgroundWorker内看了一眼。这是Result属性的内容:

public object Result
{
  get
  {
    this.RaiseExceptionIfNecessary();
    return this.result;
  }
}

RaiseExceptionIfNecessary()的内容:

protected void RaiseExceptionIfNecessary()
{
  if (this.Error != null)
    throw new TargetInvocationException(SR.GetString("Async_ExceptionOccurred"), this.Error);
  if (this.Cancelled)
    throw new InvalidOperationException(SR.GetString("Async_OperationCancelled"));
}

因此,如果取消该线程,引用Result将引发InvalidOperationException。这就是它的设计方式。

我不知道回传字符串的“最佳”方法是什么。我会说你可以在运行BackgroundWorker的同一方法中定义一个变量,并从DoWork事件中为它赋值。

你必须非常小心,UI线程上的 nothing 以某种方式绑定到变量,否则你可能会遇到问题。字符串应该是安全的,但不要开始添加到绑定到ComboBox或其他东西的列表。