任务==懒惰?

3 .net c#

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

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

var data = new Task<Data>(() => GetCurrentInternal(credentials));
Run Code Online (Sandbox Code Playgroud)

有什么变化吗?我宁愿TaskLazy?怎么样Dispose()catch(Exception)

wes*_*ton 11

相似

双方Lazy<T>Task<T>承诺以后做了一些工作,并返回类型的结果T.

差异

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

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

Lazy<T>当你打电话时,会冒出lambda引起的任何异常.Value.

Task<T>将保留lambda引起的任何异常,并在以后抛出它await task.或者,如果你task.Wait()可以在包装该异常AggregationException.关于捕获任务引发的异常的更多信息,我向您推荐这个:捕获异步方法引发的异常,并查看此http://stiller.co.il/blog/2012/12/task-wait-vs-await/

  • 是的,这是分析仪中真正应该修复的错误.当一次性用作任务时,它应该抑制警告. (4认同)
  • 还有另一种相似之处:在提供的代码中都没有意义. (3认同)

The*_*kis 11

不,Lazy<T>不一样Task<T>.


Lazy<T>懒惰评估概念的实现:

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

Task<T>未来的概念有关.

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

所有这一切,Lazy<T>Task<T>确实有一些你可能已经接受的共同点.

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

  • 哦,这是一个monad好吧 - 或者更确切地说,是一个comonad.C#类型系统创建使用monad模式的类型没有问题.C#类型系统缺乏的概念是没有办法说"我想创建一个方法,其参数只是与monad模式匹配的泛型类型". (3认同)