使用线程安全更新单例的属性

2023-12-12

我们的设置是:Asp.NET + MVC5,使用 AutoFac 进行 DI。

我们有一个类(单例),它管理各种服务的访问令牌。有时,这些令牌即将到期(不到 10 分钟),我们会请求新令牌并刷新它们。我当前的实现如下所示:

// member int used for interlocking
int m_inter = 0;

private string Token { get; set; }

private DateTimeOffset TokenExpiry { get; set; }

public SingletonClassConstructor()
{
   // Make sure the Token has some value.
   RefreshToken();
}

public string GetCredentials()
{
  if ((TokenExpiry - DateTimeOffset.UTCNow).TotalMinutes < 10)
  {
     if (Interlocked.CompareExchange(ref m_inter, 1, 0) == 0)
     {
        RefreshToken();
        m_inter = 0;
     }
  }

  return Token;
}

private void RefreshToken()
{
   // Call some stuff
   Token = X.Result().Token;
   TokenExpiry = X.Result().Expiry;
}

正如您所看到的,互锁确保只有一个线程通过,其余线程获取旧令牌。我想知道的是 - 我们是否会遇到一种奇怪的情况,即当令牌被覆盖时,另一个线程尝试读取而不是旧令牌,得到部分搞砸的结果?这个实现有什么问题吗?

Thanks!


对我来说,此实现的最大问题是您可能会在一个有效期内刷新令牌两次或多次。如果线程在检查过期条件之后但在执行之前被挂起CompareExchange(),那么另一个线程可以完成刷新操作,包括重置m_inter,在第一个线程恢复之前。理论上,这可能发生在任意多个线程上。

您的代码的其余部分不够具体,无法评论。没有任何声明Token类型,所以不清楚这是否是struct or class。和你的GetCredentials()方法被声明为返回一个Credentials值,而是返回一个Token值,因此该代码显然不是真正的代码。

If the Token类型是一个class,那么其余的实现可能就没问题了。即使在 x64 平台上,引用类型变量也可以原子分配,因此检索引用类型变量的代码Token属性值将看到旧令牌或新令牌,而不是某些损坏的中间状态。 (当然,我假设Token对象本身是线程安全的,最好是因为不可变。)

就我个人而言,我不会打扰CompareExchange()。只需使用成熟的 C#lock声明并完成它。将整个操作包含在同步块中:检查过期时间,必要时替换令牌,并返回令牌值,所有这些都来自于lock.

根据您展示的代码,我认为将整个事物封装在属性本身中并使其更有意义public。但不管怎样,只要代码检索令牌值就可以only通过这一段同步代码,证明代码正确的最简单、最可靠的方法就是使用lock。万一您发现性能问题,那么您可以考虑更难正确执行的替代实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用线程安全更新单例的属性 的相关文章

  • 在 OnModelCreating 期间设置列名称

    Issue 我目前正在尝试通过设置的属性为我的表及其列添加前缀 我正在使用实体框架核心 我已经正确地为表名添加了前缀 但我似乎无法弄清楚列的前缀 我有一种感觉 我需要使用反射 我已经留下了我的 可能很糟糕的 反思尝试 有人有办法在实体中设置
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • std::call_once 可重入且线程安全吗?

    std call once http en cppreference com w cpp thread call once是线程安全的 但它也是可重入的吗 我使用 VS2012 调试和发布 进行的测试表明 调用std call once从单
  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 多线程——更快的方法?

    我有一堂有吸气剂的课程getInt 和一个二传手setInt 在某个领域 比如说领域 Integer Int 一个类的一个对象 比如说SomeClass The setInt 这里是同步的 getInt isn t 我正在更新的值Int来自
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • 您如何填充/验证您的 ViewModel?

    我很好奇人们构建 ViewModel 的各种方式以及他们为什么选择该方法 我在这里可以想到几种方法 1 注入存储库 控制器加载模型并映射到 ViewModel 这里 ViewModel 构造函数可以采用各种集合来进行内部设置 在选择列表中
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • 为什么以下 C 程序会出现总线错误?

    我认为这是第一个失败的 strtok 调用 好久没写C了 有点不知所措 非常感谢 include
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne

随机推荐

  • 使用 Google Apps 脚本刷新从 Google 工作表粘贴到 Google 幻灯片中的表格

    这个问题在这里有一个简洁的解决方案更新链接到 Google 幻灯片的 Google Sheets 图表 function onOpen var ui SlidesApp getUi ui createMenu Custom Menu add
  • 如何从 TFS 2015 构建获取预期输出(以匹配我的 XAML 构建)?

    我们刚刚升级到 TFS2015 现场 我正在尝试设置一个构建 该构建将执行与我的 xaml 构建相同的操作 但我似乎无法构建相同的文件 这是我用来发布网站的 xaml 输出目录的图片 为此 我导航到构建文件夹 然后深入到 Published
  • 将位图图像转换为字节数组(Windows Phone 8)

    我是 Windows Phone 开发新手 我的小应用程序需要图像 照片库 中的字节数组 我尝试了很多方法来转换 但效果都不好 这是我的代码 public static byte ConvertBitmapImageToByteArray
  • 在QWebEngineView浏览器中保存html文件

    我正在尝试使用 Python QWebEngineView 创建自己的浏览器 我遵循了适用于 PyQt5 之前版本 2015 年左右 的教程 但由于最近的更新 之前代码的某些部分不再起作用 我已经修复了大多数错误 但无法执行 html 文件
  • 是否可以在 Google Glass 上使用 Android 语音识别(作为自定义服务)?

    我们有一个演示 Android 应用程序 Android 4 0 3 它将语音识别作为服务运行 并 持续 在视图上记录识别结果 我们的智能手机一切正常 我们希望在 Google Glass 沉浸式应用程序中复制此场景 但当我们尝试启动服务时
  • iOS11 UISearchBar 嵌入 UISplitViewController 时 UINavigationBar 中缺失

    使用新的 iOS 11 时似乎会发生奇怪的事情navigationItem searchController详细视图的方法UISplitViewController The searchBar在第一个演示文稿中部分显示为空白 然后出现在错误
  • .load() 在 ipad 上不起作用

    我有简单的脚本来检查图像 但它在我的 iOS 5 1 的 iPad 上无法正常工作 在图像中 我收到 jpg 流 因此加载必须在每个帧上工作 如在 big safari 中 但在 ipad 中它只触发一次 可能有一些建议吗 image lo
  • 使用指定编码记录多个模块和多个处理程序的最 Pythonic 方式是什么?

    我正在寻找有关如何完成多模块和多处理程序日志记录的具体建议 我在这里添加了简化的代码 但我不想让答案产生偏差 告诉我最佳实践是什么 我想将所有内容记录到文件中 并在控制台上发出警告 这是我的level0 py我希望它记录到指定的文件 imp
  • primefaces 自动完成功能支持 f:param 或 f:attribute?

    我读到核心 JSF 组件支持f param and f 属性标签 以便将一些值传递到服务器端以用于封闭的 UI 组件 我需要能够为 primefaces 的自动完成组件执行此操作 这样自动完成方法就能够使用由f param or f 属性
  • YouTube 视频在片段中播放时卡住

    我是 Android 新手 我正在尝试在片段加载时播放 YouTube 视频 这意味着打开应用程序时应该播放视频 当我在活动中使用它时 它可以工作 YouTubePlayerView 但是当我使用 YouTubePlayerSupportF
  • 从类型中提取调用签名

    给定一个包含调用签名和附加属性的类型 例如 export interface Foo
  • python 中使用 O(1) 空间的自底向上斐波那契

    我想使用 O 1 空间编写自下而上的斐波那契数 我的问题是 python 的递归堆栈限制了我测试大量数据 有人可以为我所拥有的提供替代或优化吗 这是我的代码 def fib in place n def fibo f2 f1 i if i
  • 激活手电筒应用程序的 LED

    我正在尝试为我的 iPhone 制作一个手电筒应用程序 我有一部 iPhone 4 想在我的项目中使用 iPhone 上的 LED 谁能帮助我开始使用它 这是一个较短的版本 您现在可以使用它来打开或关闭 LED void torchOnOf
  • 如何从 ASP.NET Web 应用程序在特定时间发送邮件

    我是 ASP NET 新手 我有一个项目正在运行 我需要每天中午12点向不同的用户发送不同的邮件 我需要知道如何实现每天在某个时间段醒来的方法 请帮助我提供尽可能多的细节 因为我是一个完全的初学者 Use 石英网 Quartz NET 是一
  • 将 Imgur API 与 Angular4 结合使用

    我正在使用 Angular 开发一个 Web 应用程序 但在使用 Imgur API 时遇到问题 我的目标是建立一个表单 用户可以选择其照片 然后将其上传到 imgur 并将链接存储在存储图像的位置 但是 我有两个问题 存储 图像的最佳方式
  • 如何构建 mtp 设备的路径(可在文件夹浏览对话框中使用)?

    我实现了从Windows PC到Android设备的文件传输 该设备通过MTP连接到计算机 复制实现已准备就绪 我使用了这个示例 http code msdn microsoft com windowsdesktop Portable De
  • NodeJS/express:缓存和 304 状态码

    当我重新加载使用express制作的网站时 我在Safari 而不是Chrome 中得到一个空白页面 因为NodeJS服务器向我发送了304状态代码 怎么解决这个问题呢 当然 这也可能只是 Safari 的问题 但实际上它在所有其他网站上都
  • 在python中设置http响应读取方法的超时

    我正在用 python 构建一个下载管理器来娱乐 有时与服务器的连接仍然存在 但服务器不向我发送数据 因此 HTTPResponse 的 读取方法永远阻止我 例如 当我从位于我国境外的服务器下载时 就会发生这种情况 这会限制其他国家 地区的
  • 如何从命令行设置列表类型的 CMake 变量

    我正在尝试做这样的事情 cmake G Visual Studio 15 2017 Win64 DCMAKE CONFIGURATION TYPES ReleaseDebug But the CMAKE CONFIGURATION TYPE
  • 使用线程安全更新单例的属性

    我们的设置是 Asp NET MVC5 使用 AutoFac 进行 DI 我们有一个类 单例 它管理各种服务的访问令牌 有时 这些令牌即将到期 不到 10 分钟 我们会请求新令牌并刷新它们 我当前的实现如下所示 member int use