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
。
如果您正在执行动态任务并行操作 ,则Result
和StartNew
都是合适的; 否则,应该避免它们。 如果您正在进行异步编程,则两者都不合适。
如果我认为await将释放调用线程但是Task.Result将阻止它,我会不会错,它会是正确的吗?
你是对的,只要任务没有同步完成。 如果是这样,使用Task.Result
或await task
将同步执行,因为await
将首先检查任务是否已完成。 否则,如果任务尚未完成,它将阻止Task.Result
的调用线程,而使用await
将同步等待任务完成。 另一个不同的是exception处理。 前者将传播AggregationException
(可能包含一个或多个exception),后者将解包并返回基础exception。
作为旁注, 使用异步包装而不是同步方法是不好的做法,应该避免。 此外,在异步方法中使用Task.Result
是导致死锁的原因,也应该避免。