2010-12-22 15 views
0

Ich versuche stundenlang, ein solches Szenario zu implementieren, aber mit Eingabeparametern und einem Rückgabewert.TPL Probleme, Fehlerbehandlung und Rückgabewerte

Dies funktioniert gut und ich bekommen, was ich erwarten:

OperationXY Faulted mindestens ein Fehler aufgetreten:

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"); 
    } 

Ausgabe dieser sein wird. Geschehen ... aber mit Fehler

Aber wenn ich dieses Beispiel ändern, ist Aufgabe Fortsetzung, wie ich nicht arbeiten, außer mehr:

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; 
    } 

}

Was will ich erreichen ist:

  • Passing einen Eingang, der für die Bearbeitung einer Aufgabe
  • Stellen Sie die Auflösung erforderlich ist, ult zu einem UI-Element
  • Handhabung Fehler, aber weiterhin "OnlyOnRanToCompletion" sowieso

Jede Hilfe willkommen

Dank

Martin

Antwort

1

Dies liegt daran, Ihr Code hat einen Fehler in es. Sie definieren myTask in Ihrer Erstellung der Fehlerbehandlungsfortsetzung neu. Die Linie:

 myTask = myTask.ContinueWith(errorTest => 

Soll heißen:

 myTask.ContinueWith(errorTest => 

Andernfalls fügen Sie die RAN Fortsetzung der Fehlerbehandlung Fortsetzung bis zur Fertigstellung, nicht auf die ursprüngliche myTask.

Dies sollte Ihren Code beheben. Der Ausgang sollte jetzt lesen:

OperationXY 
Done