C# 对等待的任务使用ContinueWith()并在内部调用task.Result

C# 对等待的任务使用ContinueWith()并在内部调用task.Result,c#,async-await,task,task-parallel-library,continuewith,C#,Async Await,Task,Task Parallel Library,Continuewith,我遇到了以下使用ContinueWith()等待结果的代码 public async Task<User> GetUser() { return await _serviceRepo.GetUserAsync() .ContinueWith(task => { return task.Result; }); } public异步任务GetUser() { return wait_serviceRepo.

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

public async Task<User> GetUser()
{
    return await _serviceRepo.GetUserAsync()
       .ContinueWith(task => 
       {
           return task.Result;
       });
}
public异步任务GetUser()
{
return wait_serviceRepo.GetUserAsync()
.ContinueWith(任务=>
{
返回任务。结果;
});
}
ContinueWith()
是否会阻止调用线程,直到任务从
GetUserAsync()
调用返回

由于
task.Result
位于计划的ContinueWith()内,因此在等待先行
任务时是否有任何内容被阻止

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

ContinueWith()
是否会阻止调用线程,直到任务从
GetUserAsync()
调用返回

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

由于
task.Result
位于计划的
ContinueWith()
内,在等待先行任务时是否有任何内容被阻止

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

这被认为是asyn/WAIT模式的最佳实践吗

不,此代码可以改写为以下格式:

public async Task<User> GetUser()
{
    return await _serviceRepo.GetUserAsync();
}
public异步任务GetUser()
{
返回wait_serviceRepo.GetUserAsync();
}
但是,如果在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;
       });
public异步任务GetUser()
{
return wait_serviceRepo.GetUserAsync()
.ContinueWith(任务=>
{
//对结果进行处理,例如,记录成功
返回任务。结果;
});
您可以这样做:

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

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

    return user;
}
public异步任务GetUser()
{
var user=await_serviceRepo.GetUserAsync();
//对结果进行处理,例如,记录成功
返回用户;
}

您没有在等待的
任务上使用
ContinueWith
。您正在等待由
ContinueWith
创建的
Task
。顺便说一句,为什么不使用
公共任务GetUser()=>\u serviceRepo.GetUserAsync();
没有理由这样做。您可以完全删除async、Wait和ContinueWith。我还将
GetUser
重命名为
GetUserAsync
,以遵循约定,并且您还可以从方法签名中删除async修饰符,甚至
返回\u serviceRepo.GetUserAsync();
直接,因为方法
GetUserAsync
的调用方将等待它,所以您可以通过直接返回任务来避免创建异步状态机开销,在这个方法中不需要等待iit,因为我们不直接在后面使用
user
变量。@DavidB对于简单方法,这是正确的d结构与上面类似。一般情况下,这种逻辑可能更复杂,简单的任务返回是不够的