await Task <t>和Task <t> .Result?</t> </t>之间有什么区别?

时间:2014-12-13 22:26:33

标签: c# multithreading async-await

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

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

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

我在这里使用await Task。如果我认为await会释放调用线程但是Task.Result会阻止它,它会不会错呢?

2 个答案:

答案 0 :(得分:46)

  

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

一般来说,是的。 await task;将&#34;产生&#34;当前的线程。 task.Result将阻止当前线程。 await是异步等待; Result是阻塞等待。

还有另一个更小的区别:如果任务在故障状态下完成(即有异常),那么await将(重新)按原样(重新)引发该异常,但是{{ 1}}将异常包装在Result

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

如果您正在执行dynamic task parallelismTask.RunResult都是合适的。否则,应该避免它们。如果您正在进行asynchronous programming,则两者都不合适。

答案 1 :(得分:4)

  

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

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

作为旁注,using asynchronous wrappers over sync methods is bad practice and should be avoided.此外,在异步方法中使用Task.Result是造成死锁的原因,也应该避免。