任务==懒惰?

时间:2015-12-18 13:42:35

标签: c# .net

public Data GetCurrent(Credentials credentials)
{ 
    var data = new Lazy<Data>(() => GetCurrentInternal(credentials));
    try
    {
        return data.Value;
    }
    catch (InvalidOperationException ex)
    {
        throw ex.InnerException;
    }
}

如果我将通话更改为以下内容:

var data = new Task<Data>(() => GetCurrentInternal(credentials));

有什么变化吗?我应该更喜欢Task而不是Lazy吗?那么Dispose()catch(Exception)呢?

3 个答案:

答案 0 :(得分:11)

的相似性

Lazy<T>Task<T>承诺稍后会做一些工作并返回T类型的结果。

的差异

Lazy<T>承诺如果需要的话,尽可能晚地完成工作,并同步进行。

然而,

Task<T>可以在您的线程执行其他工作时阻止异步工作,或阻止等待结果。

当你致电Lazy<T>时,

.Value会冒出由lambda引起的任何异常。

Task<T>将保留lambda引起的任何异常,并在await task之后将其抛出。或者,如果您task.Wait() 可以将异常包装在AggregationException中。关于捕获任务引发的异常的更多信息,我建议您参考:Catch an exception thrown by an async methodhttp://stiller.co.il/blog/2012/12/task-wait-vs-await/

答案 1 :(得分:11)

不,Lazy<T>Task<T>不同。

Lazy<T>lazy evaluation概念的实现:

  1. 它表示T值,在首次访问时同步计算,可能会也可能不会发生。
  2. 首次访问时进行评估,后续访问使用缓存值Memoization是一个密切相关的概念。
  3. 第一次访问将阻止以计算值,而后续访问将立即生成值。
  4. Task<T>future的概念有关。

    1. 它代表T值,在promise 创建时计算(通常是异步),即使没有人最终实际访问它。
    2. 所有访问产生的缓存值已经或将要在之前或将来的时间由评估机制(承诺)计算。
    3. 在计算值完成之前发生的任何访问都将阻塞,直到计算完成。在计算值完成后发生的任何访问将立即产生计算值。
    4. 所有这一切,Lazy<T>Task<T>确实有一些你可能已经接受过的共同点。

      这些类型中的每一种都是一元泛型类型,它描述了执行特定计算的唯一方式,它将产生T值(并且该计算可以方便地作为委托传递或lambda)。换句话说,这些类型中的每一种都是monad 的示例。你可以在Stack Overflow和其他地方找到一些非常good and simple explanations of what a monad is

答案 2 :(得分:4)

TaskLazy是完全不同的概念。

您使用Task执行异步操作。一些无聊的MSDN:

  

Task类表示不返回a的单个操作   值通常以异步方式执行。任务对象是一个   首先是基于任务的异步模式的核心组件   在.NET Framework 4中引入。因为工作由一个   任务对象通常在线程池线程上异步执行   而不是在主应用程序线程上同步,你可以使用   Status属性,以及IsCanceled,IsCompleted和   IsFaulted属性,用于确定任务的状态。最常见的,   lambda表达式用于指定任务的工作   执行。

Lazy用于延迟初始化对象。这意味着,只有在您调用lazyObj.Value时才会初始化您的对象。

  

使用延迟初始化来推迟创建大型或   资源密集型对象,或资源密集型的执行   任务,特别是当这种创建或执行可能不会发生时   在该计划的整个生命周期中。

     

要准备延迟初始化,请创建一个Lazy实例。   您创建的Lazy对象的type参数指定了   要延迟初始化的对象的类型。构造函数   用于创建Lazy对象的确定   初始化的特征。懒惰初始化发生了   第一次访问Lazy.Value属性。