在等待的任务上使用 ContinueWith() 并在内部调用 Task.Result

hex*_*tor 4 c# task task-parallel-library async-await continuewith

我遇到了以下使用 ContinueWith() 等待结果的代码。

public async Task<User> GetUser()
{
    return await _serviceRepo.GetUserAsync()
       .ContinueWith(task => 
       {
           return task.Result;
       });
}
Run Code Online (Sandbox Code Playgroud)

是否ContinueWith()阻塞调用线程直到任务从GetUserAsync()调用返回?

由于 位于task.Result已安排的 ContinueWith() 内,在等待前件时task是否有任何内容被阻止?

我在其他几个地方看到过这种类型的代码,这被认为是异步/等待模式的最佳实践吗?我希望GetUserAsync()调用返回结果而不是使用 aContinueWith()来等待它。

VMA*_*Atm 6

是否ContinueWith()阻塞调用线程直到任务从GetUserAsync()调用返回?

不,线程不会被阻塞,因为这是一个async操作。请注意,给定的代码等待的不是任务,而是continuation,这可能会在调试期间误导您。

既然task.Result是在ContinueWith()被调度的里面,那么在等待前置任务的时候有什么东西被阻塞了吗?

不,任务已经完成,当前线程不会被阻塞。但是,如果任务未成功完成,则会引发异常。

这被认为是异步/等待模式的最佳实践吗?

不,这段代码可以改写成以下形式:

public async Task<User> GetUser()
{
    return await _serviceRepo.GetUserAsync();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果在continuation 中有一些逻辑,像这样:

public async Task<User> GetUser()
{
    return await _serviceRepo.GetUserAsync()
       .ContinueWith(task => 
       {
           // do something with the result, for example, log the success

           return task.Result;
       });
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

public async Task<User> GetUser()
{
    var user = await _serviceRepo.GetUserAsync();

    // do something with the result, for example, log the success

    return user;
}
Run Code Online (Sandbox Code Playgroud)