2010-12-22 30 views
0

我嘗試了幾個小時來實現這樣的場景,但輸入參數和返回值。TPL問題,錯誤處理和返回值

這工作得很好,我得到我所期望的:

public class AsyncStuff2 
{ 
    public void DoAsyncStuff() 
    {    
     TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

     Task myTask = Task.Factory.StartNew(() => 
     { 
      OperationXy(); 
     }); 

     bool hadError = false; 

     myTask = myTask.ContinueWith(errorTest => 
     { 
      Console.WriteLine("Faulted"); 
      hadError = true; 

      if (errorTest.Exception != null) 
      { 
       Console.WriteLine(errorTest.Exception.Message); 
      } 
     }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler); 

     myTask.ContinueWith(another => 
     { 
      Console.WriteLine("Done"); 

      if (hadError) 
      { 
       Console.WriteLine("...but with error"); 
      } 

     }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, uiScheduler); 

    } 

    private void OperationXy() 
    { 
     Console.WriteLine("OperationXY"); 
     throw new ArgumentException("Just for Test"); 
    } 

輸出將是這樣的:

OperationXY 斷陷發生 一個或多個錯誤。 完成 ......但是,錯誤

但是,當我修改這個例子中,任務延續並不如我除了工作了:

public class AsyncStuff 
{ 

    public string Path { get; set; } 

    public void DoAsyncStuff() 
    { 
     Path = "A Input..."; 

     TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

     Task<string> myTask = Task<string>.Factory.StartNew((input) => 
     { 
      return OperationXy(Path); 

     }, Path, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); 

     bool hadError = false; 

     myTask = myTask.ContinueWith<string>(errorTest => 
     { 
      Console.WriteLine("Faulted"); 
      hadError = true; 

      if (errorTest.Exception != null) 
      { 
       Console.WriteLine(errorTest.Exception.Message); 
      } 

      return null; 

     }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler); 

     myTask.ContinueWith(another => 
     { 
      Console.WriteLine("Done, Result: {0}", myTask.Result); 

      if (hadError) 
      { 
       Console.WriteLine("...but with error"); 
      } 

     }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, uiScheduler); 
    } 

    private string OperationXy(string returnThat) 
    { 
     Console.WriteLine("OperationXY, Input ({0})", returnThat); 

     //throw new ArgumentException("Just for Test"); 

     return returnThat; 
    } 

}

我想實現的是:

  • 將處理所需的輸入傳遞給任務
  • 設置res ULT的UI元素
  • 處理錯誤,而是繼續 「OnlyOnRanToCompletion」 反正

任何幫助表示讚賞

感謝

馬丁

回答

1

這是因爲您的代碼中的錯誤它。您在創建錯誤處理延續時重新定義myTask。行:

 myTask = myTask.ContinueWith(errorTest => 

應改爲:

 myTask.ContinueWith(errorTest => 

否則,你所添加的運行完成延續錯誤處理延續,而不是原來的myTask。

這應該修復你的代碼。輸出現在應爲:

OperationXY 
Done