Reputation: 5458
I'm trying for hours to implement a scenario like this, but with input parameters and a return value.
This works fine and I get what I expect:
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");
}
Output will be this:
OperationXY Faulted One or more errors occurred. Done ...but with error
But when I modify this example, task continuation does not work as i except anymore:
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;
}
}
What I want to achieve is:
Any help appreciated
Thanks
Martin
Upvotes: 0
Views: 923
Reputation: 13733
This is because your code has a bug in it. You redefine myTask in your creation of the error handling continuation. The line:
myTask = myTask.ContinueWith(errorTest =>
Should read:
myTask.ContinueWith(errorTest =>
Otherwise you are adding the ran to completion continuation to the error handling continuation, not to the original myTask.
This should fix your code. The output should now read:
OperationXY
Done
Upvotes: 1