我知道以前有人问过这个问题,但是在谷歌搜索之后我没有得到正确的答案。
我有这些代码行:
Task.Run(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"), TaskContinuationOptions.OnlyOnFaulted);
Task.Factory.StartNew(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"),TaskContinuationOptions.OnlyOnFaulted);
DoSomething
成功运行后,Task.Run
抛出 TaskCanceledException
而 Task.Factory.StartNew
工作美好的。为什么?
进一步阅读:
Stephen Clearly on why not use Task.Factory.StartNew
MSDN Link
更新 2: 示例代码:
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);
阅读更多 here .
如果你通过 CancellationToken.None
, TaskCreationOptions.DenyChildAttach
和 TaskScheduler.Default
Task.Factory.StartNew
的参数参数你应该看到相同的结果。
关于c# - Task.Run 和 Task.Factory.StartNew 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608671/