任务==懒惰?

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

如果我将呼叫更改为以下内容:

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

有什么变化吗? 我应该更喜欢Task over Lazy吗? Dispose()catch(Exception)怎么样?

相似

LazyTask承诺稍后会做一些工作并返回类型为T的结果。

差异

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

但是,当您的线程执行其他工作或阻止等待结果时, Task可以异步执行其工作。

当你调用.Value时, Lazy会冒出lambda引起的任何exception。

Task将保留lambda引起的任何exception,并在await task时将其抛出。 或者如果你task.Wait()可能会AggregationException包装exception。 关于捕获任务引发的exception的更多信息,我向您推荐这一点: 捕获异步方法引发的exception,以及此http://stiller.co.il/blog/2012/12/task-wait-vs-await/

不, LazyTask


Lazy是懒惰评估概念的一种实现:

  1. 它表示将在第一次访问时同步计算T值,其可能会或可能根本不会发生。
  2. 评估在首次访问时发生, 后续访问使用缓存值 。 记忆是一个密切相关的概念。
  3. 第一次访问将阻塞以计算值,而后续访问将立即产生该值。

Task与未来的概念有关。

  1. 它表示将在创建其承诺时计算(通常是异步)T值,即使没有人最终实际访问它。
  2. 所有访问都会产生一个缓存值该缓存值已经或将要在之前或将来的时间由评估机制(承诺)计算。
  3. 在计算值完成之前发生的任何访问都将阻塞,直到计算完成。 在计算值完成后发生的任何访问将立即产生计算值。

所有这些, LazyTask确实有一些你可能已经接受过的共同点。

这些类型中每一种都是一元generics类型,它描述了执行特定计算的唯一方法,该方法将产生T值(并且该计算可以方便地作为委托或lambda传递)。 换句话说, 这些类型中的每一个都是monad的示例 。 您可以在Stack Overflow和其他地方找到一些非常好的简单解释monad的内容 。

TaskLazy是完全不同的概念。

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

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

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

使用延迟初始化来推迟创建大型或资源密集型对象,或者执行资源密集型任务,尤其是在程序生命周期内可能不会发生此类创建或执行时。

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