c# - 如果我使用 new Task(action) -> .Start() 而不是 Task.Run() 创建任务,为什么在调用任何异步方法时任务会停止执行?
问题描述
我发现如果使用以下方式构造一个新任务:
var task = new Task(async action); task.Start();
,任何异步方法( , 等)的任何调用都会await Task.Delay()
忽略await new WebClient().DownloadStringAsync()
运算await
符并立即返回主线程。
如果我使用Task.Run(async action)
方式运行相同的操作,那么相同的代码将按预期工作。
示例代码:
class Program
{
static async Task Main()
{
// way1 - it's working
var goodTask = Task.Run(async () => await ProblemMethod("goodTask"));
await goodTask;
Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(goodTask)} is finished.");
// way2 - it fails without any exceptions on line with GetRequestStreamAsync
var poorTask = new Task(async () => await ProblemMethod("poorTask"));
poorTask.Start();
await poorTask;
Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(poorTask)} is finished.");
Console.ReadLine();
}
static async Task ProblemMethod(string taskName)
{
Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: It's a first line.");
await Task.Delay(2000);
Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: It's a last line.");
}
}
控制台输出:
goodTask :: 18:52:50 :: It's a first line.
goodTask :: 18:52:52 :: It's a last line.
18:52:52 :: goodTask is finished.
poorTask :: 18:52:52 :: It's a first line.
18:52:52 :: poorTask is finished.
poorTask :: 18:52:54 :: It's a last line.
为什么会有如此奇怪的行为?而且,是的,我知道首选和推荐的方法是通过 Task.Run 或 Task.Factory.StartNew 立即运行任务,但是如果我不想立即运行我的任务该怎么办?
解决方案
答案在这里讨论。本质上,Task
构造需要 aAction<>
而不是 a Func<>
,因此异步委托并没有真正被这样对待。
推荐阅读
- java - Java + Selenium 会话 ID 为空。调用 quit() 后使用 WebDriver
- javascript - 根据用户的输入创建查询
- javascript - 使用javascript比较数组中元素的最佳方法?
- android - 如果我关闭启动它的应用程序,我可以在 Android Studio 中停止服务吗?
- c++ - Magick++ 不读取图像
- python - 将 xarray.plot.line 与颜色图一起使用
- android - 仅当我释放对 RecyclerView 列表的触摸时,才使 ItemTouchHelper 运行 OnMove
- javascript - 上传多个文件时出现 AWS S3 'RequestTimeTooSkewed' 错误
- recursion - C#中父子的分层求和
- python - Ansible 因 ModuleNotFoundError 失败:没有名为“pexpect”的模块