await Task和Task.Result之间有什么区别?

16 浏览
0 Comments

await Task和Task.Result之间有什么区别?

public async Task GetName(int id)
{
    Task nameTask = Task.Factory.StartNew(() => string.Format("Name matching id {0} = Developer", id));
    return nameTask.Result;
}

在上面的方法的返回语句中,我使用了Task.Result属性。

public async Task GetName(int id)
{
     Task nameTask = Task.Factory.StartNew(() => string.Format("Name matching id {0} = Developer", id));
     return await nameTask;
}

在这里,我使用了await Task。如果我认为await将释放调用线程,而Task.Result会阻塞它,那我就不会错了,是吗?

admin 更改状态以发布 2023年5月22日
0
0 Comments

如果我认为 await 会释放调用线程而 Task.Result 会阻塞它,那么我应该是对的吧?

你是正确的,只要该任务没有同步完成。如果是同步完成,使用 Task.Resultawait task 将同步执行,因为 await 将首先检查任务是否已完成。否则,如果任务没有完成,使用 Task.Result 将阻塞调用线程,而使用 await 将异步等待任务完成。另一个不同之处是异常处理。前者将传播 AggregationException(其中可能包含一个或多个异常),而后者将解包并返回基础异常。

顺便提一下,使用异步包装器覆盖同步方法是不良实践,应该避免。 此外,在异步方法内部使用 Task.Result 会导致死锁,也应避免。

0
0 Comments

如果我认为await将释放调用线程而Task.Result将阻塞它,这样说是否正确?

一般而言,是的。 await task; 将“让出”当前线程。 task.Result 将阻塞当前线程。 await是异步等待,Result是阻塞等待。

还有一个更小的区别:如果任务以失败的状态(即异常)完成,则 await将原样(重新)引发异常,而Result将在AggregateException中包装异常。

顺便提一下,避免使用Task.Factory.StartNew。它几乎从来不是正确的方法。如果需要在后台线程上执行工作,请使用 Task.Run

如果正在进行动态任务并行,则ResultStartNew都是适当的;否则,应避免使用它们。如果进行异步编程,则两者都不适用。

0