这两者的区别是什么?运行和Task.Factory.StartNew

本文关键字:运行 Task Factory StartNew 是什么 区别 | 更新日期: 2023-09-27 18:18:03

我知道这个问题以前有人问过,但是我在谷歌搜索了SO之后没有得到正确的答案。

我有这些行代码:

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工作正常。为什么?

进一步阅读:很清楚为什么不使用Task.Factory.StartNew
MSDN链接

UPDATE 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.Factory.StartNew

任务。Run的实际实现逻辑与Run相同Task.Factory。StartNew,只是传入一些默认参数。当你将Action传递给Task。运行:

Task.Run(someAction);

完全等价于:

Task.Factory.StartNew(someAction, 
    CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

点击这里阅读更多。

如果您为Task.Factory.StartNew参数传递CancellationToken.None, TaskCreationOptions.DenyChildAttachTaskScheduler.Default参数,您应该看到相同的结果