缓存 [n async] 工厂方法的结果,前提是它不会抛出异常

2023-12-27

更新:在 @usr 指出我错误地假设后进行了重大修改Lazy<T>的默认线程安全模式是LazyThreadSafetyMode.PublicationOnly...

我想通过一个惰性计算值async工厂方法(即它返回Task<T>)并在成功时将其缓存。在例外情况下,我希望我可以使用它。然而我不想成为牺牲品异常缓存行为 http://theburningmonk.com/2013/04/be-lazy-but-be-ware-of-initialization-exception/ that Lazy<T>处于默认模式(LazyThreadSafetyMode.ExecutionAndPublication)

异常缓存:当您使用工厂方法时,异常会被缓存。也就是说,如果工厂方法在线程第一次尝试访问 Lazy 对象的 Value 属性时抛出异常,则每次后续尝试都会抛出相同的异常。这可确保每次调用 Value 属性都会产生相同的结果,并避免不同线程获得不同结果时可能出现的细微错误。 Lazy 代表实际的 T,否则该 T 会在较早的某个时刻(通常在启动期间)初始化。早期的失败通常是致命的。如果存在可恢复故障的可能性,我们建议您将重试逻辑构建到初始化例程(在本例中为工厂方法)中,就像不使用延迟初始化时一样。

斯蒂芬·图布有一个AsyncLazy课堂和写作 http://blogs.msdn.com/b/pfxteam/archive/2011/01/15/asynclazy-lt-t-gt.aspx这似乎是正确的:

public class AsyncLazy<T> : Lazy<Task<T>>
{
    public AsyncLazy(Func<Task<T>> taskFactory) :
        base(() => Task.Factory.StartNew(() => taskFactory()).Unwrap())
    { }

    public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); }
}

但这实际上与默认行为相同Lazy<T>- 如果出现问题,将不会重试。

我正在寻找一个Task<T>兼容的等价物Lazy<T>(Func<T>, LazyThreadSafetyMode.PublicationOnly),即它应该按照指定的方式运行:-

锁定的替代方案 在某些情况下,您可能希望避免 Lazy 对象的默认锁定行为的开销。在极少数情况下,可能会出现死锁。在这种情况下,您可以使用 Lazy(LazyThreadSafetyMode) 或 Lazy(Func, LazyThreadSafetyMode) 构造函数,并指定 LazyThreadSafetyMode.PublicationOnly。如果多个线程同时调用 Value 属性,这使得 Lazy 对象能够在每个线程上创建延迟初始化对象的副本。 Lazy 对象确保所有线程都使用延迟初始化对象的同一实例,并丢弃未使用的实例。因此,减少锁定开销的代价是您的程序有时可能会创建和丢弃昂贵对象的额外副本。在大多数情况下,这是不可能的。 Lazy(LazyThreadSafetyMode) 和 Lazy(Func, LazyThreadSafetyMode) 构造函数的示例演示了此行为。

重要的

当您指定 PublicationOnly 时,即使指定工厂方法,也永远不会缓存异常。

有整箱吗,Nito.AsyncEx或者类似的结构可能很适合这里?如果做不到这一点,任何人都可以看到一种优雅的方式来门控“正在进行的尝试”位(我同意每个调用者以与Lazy<T>( ..., (LazyThreadSafetyMode.PublicationOnly)确实如此)但仍然有这个和缓存管理被整齐地封装?


这是否接近您的要求?

该行为介于两者之间ExecutionAndPublication and PublicationOnly.

当初始化程序正在进行时,所有调用Value将被交给相同的任务(该任务被暂时缓存,但随后可能成功或失败);如果初始化程序成功,则已完成的任务将被永久缓存;如果初始化失败,则下一次调用Value将创建一个全新的初始化任务,并且该过程再次开始!

public sealed class TooLazy<T>
{
    private readonly object _lock = new object();
    private readonly Func<Task<T>> _factory;
    private Task<T> _cached;

    public TooLazy(Func<Task<T>> factory)
    {
        if (factory == null) throw new ArgumentNullException("factory");
        _factory = factory;
    }

    public Task<T> Value
    {
        get
        {
            lock (_lock)
            {
                if ((_cached == null) ||
                    (_cached.IsCompleted && (_cached.Status != TaskStatus.RanToCompletion)))
                {
                    _cached = Task.Run(_factory);
                }
                return _cached;
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缓存 [n async] 工厂方法的结果,前提是它不会抛出异常 的相关文章

  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • 将 System.Windows.Forms.Keys 序列转换为 Char

    有没有办法转换由 Keys 枚举表示的击键序列 即System Windows Forms Keys 在一个字符中 例如 Keys Oem4进而Keys A产生 char 它一定存在于 WinAPI 中的某个地方 因为当我在文本框中按下按键
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 异步和协程与任务队列

    我一直在阅读有关 python 3 中的 asyncio 模块的内容 以及更广泛地了解 python 中的协程的内容 但我不明白是什么让 asyncio 成为如此出色的工具 我的感觉是 你可以用协程做的所有事情 通过使用基于多处理模块 例如
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的

随机推荐

  • 上传到 FTP 中的文件夹吗?

    我正在使用以下代码来学习如何使用 FTP 加载文件 如何设置文件上传的路径或文件夹 using System using System IO using System Net using System Text namespace Exam
  • Javascript:声明全局使用的函数的最佳方法?

    我的 javascript 文件变得相当大 3000 多行 我对如何布局我的文件和 delare 函数以便它们可以在文件中的任何位置调用感到困惑 总结一下我的 JS 文件目前看起来有点像这样 ALL GLOBAL VARIABLES FIR
  • SQL查询查找ID不在另一个表中的记录

    我在数据库中有两个具有绑定主键的表 我想在它们之间找到一个不相交的集合 例如 Table1 ID Name 1 John 2 Peter 3 Mary Table2 ID Address 1 address2 2 address2 那么我如
  • 异常断点 - LLDB 结果与 GDB

    我专门搜索了这个问题的主题 但没有找到任何与我的经历相近的内容 如果我忽略了答案 请原谅我 我熟悉 GDB 和异常点 断点等 但是下面的 GDB 与 LDB 调试测试让我没有得到合理的回应 全局测试值 Xcode 4 2 1 新的单一窗口项
  • Android推送通知-如何获取设备ID

    我陷入了使用 Google 云通知创建推送通知的过程 我正在做的是我应该获取设备的设备 ID 的部分 以便稍后当我需要发送推送通知时可以使用该设备 ID 所以我有这个代码 GCMRegistrar checkDevice this GCMR
  • 在 Android 中创建选项菜单

    我正在尝试在我的 Android 程序中创建选项菜单 我正在使用以下代码来扩展选项菜单 Override public boolean onCreateOptionsMenu Menu menu super onCreateOptionsM
  • 如何保存单选按钮的状态

    我制作了 4 个单选按钮 并希望在单击其中任何一个按钮时保存状态 然后希望在应用程序中使用该保存的状态 我该怎么做 myOption1 setChecked true myOption2 setChecked true myOption3
  • 将 char 数组转换为字符串

    如何使用 Arduino 将字符数组转换为字符串 char charArray String string String charArray This doesn t work String 类型的初始化与 C 构造函数类似 String
  • 您如何说服您的经理您的项目需要大规模重构? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我作为承包商加入了一个铁路项目 该项目已经进行了一年多 该代码由大约 10 名不同的开发人员编写 其中大多数也是承包商 他们有不同的代码风格 其
  • 将 `do` 表示法 `addStuff` 转换为 `>>=`

    向你学习 Haskell http learnyouahaskell com for a few monads more reader提出了addStuff功能 import Control Monad Instances addStuff
  • 确定红宝石的位置

    如何确定红宝石的位置 你可以试试 gem which rails 获取特定宝石的位置 或者 echo GEM HOME 获取您的宝石的主目录
  • 计算 JavaScript 对象中 true 的数量

    假设我有以下对象 items 1 true 2 false 3 true 4 true 我如何计算正确的数量 在本例中 这是一个返回数字 3 的简单函数 You can reduce物体的values 胁迫trues to 1并将它们添加到
  • Python elasticsearch.helpers.scan 示例

    有人可以提供 python elasticsearch helpers 客户端的扫描 API 示例吗 res elasticsearch helpers scan 如何使用 res 对象获取 elasticsearch 的所有结果 The
  • JavaScript 版本如何与 ECMAScript 版本关联?

    例如 map https developer mozilla org en JavaScript Reference Global Objects Array map是 在 JavaScript 1 6 中实现的 这是 ES5 方法吗 1
  • 如何使 JMX 自定义身份验证起作用?

    我在 JMX 上使用基于密码和访问文件的身份验证 在构建 JMXConnectorServer 时 我使用属性名称并且工作正常 Map
  • 如何在C#中获取HTTP Post数据?

    我正在使用 Mailgun API 有一个部分我需要向他们提供一个 URL 然后他们将通过 HTTP Post 一些数据给我 我提供这个网址 http test com MailGun Webhook aspx http test com
  • Android FM 信号强度

    我想知道 Android 中的 FM 收音机信号强度 为此我是否必须与硬件交互 或者有没有什么API可以直接给出信号强度的值 某些手机 提供 FM 收音机 不管怎样 你必须有一个内置的 FM 调谐器 收音机 为此我必须与 硬件与否 是的 当
  • Matlab OOP 从对象数组访问属性

    Matlab 新手来自 C C 我有一个对象数组 我试图访问数组中每个对象的值并将它们连接到一个变量中 Class sample properties GetAccess public SetAccess public ID Value e
  • 如果存在特定 cookie,则绕过 Akamai 的特定 URL

    如果存在指定的 cookie 即 如果用户登录到特定页面 我希望 Akamai 不缓存某些 URL 我们可以与 Akamai 合作吗 好消息是 我过去曾在 Top Gear 网站 www topgear com uk 上这样做过 其逻辑是
  • 缓存 [n async] 工厂方法的结果,前提是它不会抛出异常

    更新 在 usr 指出我错误地假设后进行了重大修改Lazy