将常规匿名函数和异步匿名函数传递给 Task.Run 以进行异步工作的区别
Difference between passing a regular and async anonymous function to Task.Run for asynchronous work
有什么区别
ResultType result = await Task.Run(() => GetResultAsync())
和
ResultType result = await Task.Run(async() => await GetResultAsync())
我推测前者会触发并忘记 GetResultAsync()
,因为它没有等待,但它是如何得到结果的呢?我很惊讶前者Task.Run
的return类型是Task<ResultType>
而不是Task<Task<ResultType>>
。
在您开始的 'Task.Run' 的第一行,立即 return 是 'GetResultAsync' 的结果。然而,该结果是一个可以等待的任务(由您的'await')。
所以,你实际上 'await' 'GetResultAsync' 方法。
在第二行中,您启动了一个不会立即 return 的任务,而是等到 'GetResultAsync'(异步调用)完成。您的任务 return 类型是 'ResultType'。
所以你 'await' 你自己的任务,在等待 'GetResultAsync' 方法后,它只会 return。
最后,他们都完成了相同的结果,但方式略有不同。
从结果的角度来看,两者都是一样的。在这两种情况下,都使用了重载 Task.Run<TResult>(Func<Task<TResult>> function)
来在内部解包任务 - 这就是结果为 Task<ResultType>
的原因。它们之间的差异相当于
之间的差异
static Task<T> Compute()
{
return GetAsyncResult();
}
和
static async Task<T> Compute()
{
return await GetAsyncResult();
}
在第一种情况下,promise 只是传递回调用者,而在第二种情况下,状态机由编译器围绕 Compute
方法构建。
有什么区别
ResultType result = await Task.Run(() => GetResultAsync())
和
ResultType result = await Task.Run(async() => await GetResultAsync())
我推测前者会触发并忘记 GetResultAsync()
,因为它没有等待,但它是如何得到结果的呢?我很惊讶前者Task.Run
的return类型是Task<ResultType>
而不是Task<Task<ResultType>>
。
在您开始的 'Task.Run' 的第一行,立即 return 是 'GetResultAsync' 的结果。然而,该结果是一个可以等待的任务(由您的'await')。 所以,你实际上 'await' 'GetResultAsync' 方法。
在第二行中,您启动了一个不会立即 return 的任务,而是等到 'GetResultAsync'(异步调用)完成。您的任务 return 类型是 'ResultType'。 所以你 'await' 你自己的任务,在等待 'GetResultAsync' 方法后,它只会 return。
最后,他们都完成了相同的结果,但方式略有不同。
从结果的角度来看,两者都是一样的。在这两种情况下,都使用了重载 Task.Run<TResult>(Func<Task<TResult>> function)
来在内部解包任务 - 这就是结果为 Task<ResultType>
的原因。它们之间的差异相当于
static Task<T> Compute()
{
return GetAsyncResult();
}
和
static async Task<T> Compute()
{
return await GetAsyncResult();
}
在第一种情况下,promise 只是传递回调用者,而在第二种情况下,状态机由编译器围绕 Compute
方法构建。