【发布时间】:2022-11-30 10:26:15
【问题描述】:
我很清楚(感谢 Stephen Toub)通常不推荐使用 new Task(...) 构建任务,通常更愿意使用 Task.Run,但是当将异步 lambda 作为要运行的任务?我在生产代码中遇到过类似的东西,所以下面的代码是一个高度人为设计的简单示例。
当将异步 lambda 作为任务传递给 Task.Factory.StartNew 和 new Task(...)(后跟 Task.Start)时,即使我们等待返回的任务,lambda 也没有完成。但是,它在使用 Task.Run 时确实如此 - 这里有什么区别?
(Stephen Toub 指出 Task.Run 完全等同于
Task.Factory.StartNew(SomeTask
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default);
看 https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/
这是我的代码:
using System;
using System.Threading.Tasks;
using System.Threading;
namespace TaskDelay
{
class Program
{
static readonly long t0 = DateTime.Now.Ticks;
private static void Main()
{
Console.WriteLine($"{Time} Starting t1");
var t1 = new Task(async () => await F1(5000, "Task 1"));
t1.Start();
t1.Wait();
Console.WriteLine($"{Time} Starting t2");
var t2 = Task.Factory.StartNew(async () => await F1(5000, "Task 2"),
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default);
t2.Wait();
Console.WriteLine($"{Time} Starting t3");
var t3 = Task.Run(async () => await F1(2000, "Task 3"));
t3.Wait();
Console.WriteLine($"{Time} State of {nameof(t1)} is {t1.Status}");
Console.WriteLine($"{Time} State of {nameof(t2)} is {t2.Status}");
Console.WriteLine($"{Time} State of {nameof(t3)} is {t3.Status}");
}
private static async Task F1(int delay, string taskName)
{
await Console.Out.WriteLineAsync($"{Time} Started to run F1 for {taskName}");
await Task.Delay(delay);
await Console.Out.WriteLineAsync($"{Time} Finished running F1 for {taskName}");
}
private static string Time => $"{(int)((DateTime.Now.Ticks - t0) / 10_000),5} ms:";
}
}
输出是
请注意,我们永远不会看到“已完成任务 1 的 F1 运行”或“已完成任务 2 的 F1 运行”。
【问题讨论】:
-
@shingo - 不,不是。这个问题是在问为什么有几种方法可以做同样的事情。我的问题是指出至少两种方法之间的差异并询问为什么会这样。
-
“
Task.Factory.StartNew(SomeTask”-- 我建议将SomeTask重命名为SomeAsyncMethod或SomeAsyncDelegate。Task不是方法! -
@TheodorZoulias 但接受的答案与您在下面的答案中发布的链接相同。所以答案就在那里
-
Stephen Toub states that Task.Run is exactly equivalent to- 他说那些是完全等价的通过Action时.但是您的代码没有传递Action(它传递的是Func<Task>),所以它们是不是相当于你的情况。
标签: c# lambda async-await task task-parallel-library