为什么如果我使用new Task(action) -> .Start()来创建任务,而不是使用Task.Run(),调用任何异步方法时任务会停止执行?
为什么如果我使用new Task(action) -> .Start()来创建任务,而不是使用Task.Run(),调用任何异步方法时任务会停止执行?
我发现如果按照以下方式构建一个新的任务:\nvar task = new Task(async action); task.Start();
,\n任何对任何异步方法的调用(await Task.Delay()
,await new WebClient().DownloadStringAsync()
等)都会忽略await
运算符,并立即返回到主线程。\n如果我使用Task.Run(async action)
方式运行相同的操作,那么相同的代码将按预期工作。\n示例代码:\n
class Program { static async Task Main() { // 第一种方式 - 它可以正常工作 var goodTask = Task.Run(async () => await ProblemMethod("goodTask")); await goodTask; Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(goodTask)}已完成。"); // 第二种方式 - 在调用GetRequestStreamAsync的行上没有任何异常,但是失败了 var poorTask = new Task(async () => await ProblemMethod("poorTask")); poorTask.Start(); await poorTask; Console.WriteLine($"{DateTime.Now:HH:mm:ss} :: {nameof(poorTask)}已完成。"); Console.ReadLine(); } static async Task ProblemMethod(string taskName) { Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: 这是第一行。"); await Task.Delay(2000); Console.WriteLine($"{taskName} :: {DateTime.Now:HH:mm:ss} :: 这是最后一行。"); } }
\n控制台输出:\ngoodTask :: 18:52:50 :: 这是第一行。\ngoodTask :: 18:52:52 :: 这是最后一行。\n18:52:52 :: goodTask已完成。\npoorTask :: 18:52:52 :: 这是第一行。\n18:52:52 :: poorTask已完成。\npoorTask :: 18:52:54 :: 这是最后一行。\n
\n为什么会有这种奇怪的行为?是的,我知道首选和推荐的方式是立即运行任务,通过Task.Run或Task.Factory.StartNew,但如果我不想立即运行我的任务,我该怎么办?
这个问题的出现的原因是,当使用`new Task(action).Start()`创建一个任务时,该任务的构造函数接受的是一个`Action`委托,而不是一个`Func`委托。因此,异步委托实际上并没有被正确地处理。
解决方法是改用`Task.Run()`方法来创建任务。`Task.Run()`方法接受一个`Func
在实际应用中,如果需要执行异步方法,并且希望任务能够正确地执行,可以使用以下代码:
Task.Run(async () => { await YourAsyncMethod(); });
使用`Task.Run()`方法创建任务并在其中调用异步方法,可以确保任务能够正确地执行异步操作。这样可以避免使用`new Task(action).Start()`时可能出现的问题。
,使用`new Task(action).Start()`创建任务时,由于异步委托没有被正确处理,任务可能会停止执行。为了解决这个问题,可以使用`Task.Run()`方法来创建任务,并在其中调用异步方法。这样可以确保任务能够正确地执行异步操作。