2014-01-10 49 views
1

如何取消背景工作並返回錯誤消息。我知道您可以使用DoWorkEventArgs e.Results將結果傳遞迴主線程,但當取消子線程時,e.Results會被覆蓋。例如:將結果從已取消的BackgroundWorker線程傳遞迴主線程

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

你爲什麼取消它?根據[文檔](http://msdn.microsoft.com/en-us/library/system.componentmodel.runworkercompletedeventargs.result(v = vs.110).aspx),Result'屬性將引發一個InvalidOperationException '如果你取消工作。那麼,爲什麼你這樣做**和**期待*結果*?基本上你的問題是閱讀「文檔說,當我做X時,Y會發生,我正在做X.爲什麼Y發生?我怎樣才能避免Y發生?」。我會(天真地)假設答案是「不要做X」。所以不要取消工作。 –

回答

1

如果你的長時間運行過程被取消了,它不會有真正的「結果」,因爲過程沒有完成。

按照documentation:訪問結果屬性之前

你RunWorkerCompleted事件處理程序應經常檢查錯誤和取消的屬性。如果引發異常或操作被取消,則訪問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線程以某種方式綁定到變量或者你可能會遇到問題。一個字符串應該是安全的,但不要開始添加綁定到ComboBox或其他東西的列表。

相關問題