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

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

在上面的方法return语句我使用Task.Result属性。

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

我在这里使用等待任务。 如果我认为await将释放调用线程但是Task.Result将阻止它,我会不会错,它会是正确的吗?

如果我认为await将释放调用线程但是Task.Result将阻止它,我会不会错,它会是正确的吗?

一般来说,是的。 await task; 将“屈服”当前线程。 task.Result将阻止当前线程。 await是异步等待; Result是阻塞等待。

还有一个更小的区别:如果任务在故障状态下完成(即有exception),则await将(重新)按原样引发该exception,但Result会将exception包装在AggregateException

作为旁注,请避免使用Task.Factory.StartNew 。 它几乎从来都不是正确的使用方法。 如果您需要在后台线程上执行工作,请选择Task.Run

如果您正在执行动态任务并行操作 ,则ResultStartNew都是合适的; 否则,应该避免它们。 如果您正在进行异步编程,则两者都不合适。

如果我认为await将释放调用线程但是Task.Result将阻止它,我会不会错,它会是正确的吗?

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

作为旁注, 使用异步包装而不是同步方法是不好的做法,应该避免。 此外,在异步方法中使用Task.Result是导致死锁的原因,也应该避免。