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