I know this question has been asked before, but I didn't get the right answer after googling SO.
I have these lines of code:
Task.Run(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"), TaskContinuationOptions.OnlyOnFaulted);
Task.Factory.StartNew(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"),TaskContinuationOptions.OnlyOnFaulted);
After a successful run of DoSomething, Task.Run throws TaskCanceledException while Task.Factory.StartNew works fine. Why?
further reading:
Stephen Clearly on why not use Task.Factory.StartNew
MSDN Link
UPDATE 2: Sample Code:
private async void button27_Click(object sender, EventArgs e)
{
var r = new Random(System.DateTime.Now.Millisecond);
await Task.Factory.StartNew(
() => {
Divide(r.Next(100), r.Next(-1, 10));
Log.Information("Divide Done!");
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default)
.ContinueWith(
t => {
Log.Error(t.Exception,"There is an exception on Divide");
},
TaskContinuationOptions.OnlyOnFaulted);
}
private static void Divide(int a, int b)
{
var c = a/b;
}
Task.Run is actually implemented in terms of the same logic used for Task.Factory.StartNew, just passing in some default parameters. When you pass an Action to Task.Run:
Task.Run(someAction);
that’s exactly equivalent to:
Task.Factory.StartNew(someAction,
CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
Read more here.
If you pass CancellationToken.None, TaskCreationOptions.DenyChildAttach and TaskScheduler.Default arguments for Task.Factory.StartNew parameters you should see the same result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With