在 C# 中访问简单的布尔标志时,是否需要锁定或标记为易失性?

2023-12-23

假设您有一个在后台线程上运行的简单操作。您希望提供一种方法来取消此操作,因此您创建一个布尔标志,并从取消按钮的单击事件处理程序将其设置为 true。

private bool _cancelled;

private void CancelButton_Click(Object sender ClickEventArgs e)
{
    _cancelled = true;
}

现在您正在从 GUI 线程设置取消标志,但您正在从后台线程读取它。访问布尔值之前需要锁定吗?

您是否需要这样做(显然也锁定按钮单击事件处理程序):

while(operationNotComplete)
{
    // Do complex operation

    lock(_lockObject)
    {
        if(_cancelled)
        {
            break;
        }
    }
}

或者这样做是否可以接受(没有锁):

while(!_cancelled & operationNotComplete)
{
    // Do complex operation
}

或者将 _cancelled 变量标记为易失性怎么样。有必要吗?

[我知道有一个带有内置CancelAsync()方法的BackgroundWorker类,但我对这里锁定和线程变量访问的语义和使用感兴趣,而不是具体的实现,代码只是一个例子。]

似乎有两种理论。

1)因为它是一个简单的内置类型(并且在.net中对内置类型的访问是原子的)并且因为我们只在一个地方写入它并且只在后台线程上读取,所以不需要锁定或标记为易失性。
2)您应该将其标记为易失性,因为如果不这样做,编译器可能会优化 while 循环中的读取,因为它认为没有任何东西能够修改该值。

哪种技术是正确的? (为什么?)

[编辑:对此似乎存在两种明确定义且对立的思想流派。我正在寻找对此的明确答案,因此如果可能的话,请发表您的理由并在您的答案中引用您的来源。]


首先,线程很棘手;-p

是的,尽管有所有相反的谣言,但它is被要求either use lock or volatile(但不是两者)当访问bool来自多个线程。

对于简单类型和访问,例如退出标志(bool), then volatile就足够了 - 这确保线程不会将值缓存在其寄存器中(意味着:其中一个线程永远不会看到更新)。

对于较大的值(其中原子性是一个问题),或者您想要同步sequence操作(一个典型的例子是“如果不存在并添加”字典访问),lock更加通用。这充当内存屏障,因此仍然为您提供线程安全性,但提供其他功能,例如脉冲/等待。请注意,您不应该使用lock在值类型或string; nor Type or this;最好的选择是拥有自己的锁定对象作为字段(readonly object syncLock = new object();)并锁定这一点。

举个例子,如果你不同步,它会严重中断(即永远循环) -see here https://stackoverflow.com/questions/458173/can-a-c-thread-really-cache-a-value-and-ignore-changes-to-that-value-on-other-th/458193#458193.

为了跨越多个程序,像这样的操作系统原语Mutex or *ResetEvent可能也很有用,但这对于单个 exe 来说太过分了。

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

在 C# 中访问简单的布尔标志时,是否需要锁定或标记为易失性? 的相关文章

  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • *.tlb 文件在运行时使用过吗?

    我正在开发一个通过 COM 互操作公开一些 NET API 的产品 作为构建的一部分 我们为所有此类程序集生成 tlb 文件 并将它们作为单独 SDK 包的一部分提供 我们的客户可以在我们的产品之上安装 SDK 并创建使用我们的 COM A
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

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

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐

  • 从 void 函数返回[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从函数返回哪种更正确的方法 void function blah some code OR void function blah some co
  • 如何使用 Chef 菜谱来设置环境变量?

    如何使用 Chef 菜谱来设置环境变量 我需要使用 Chef 食谱设置环境变量 您能提供一个如何实现这一目标的示例吗 如果您需要严格在 Chef 进程内设置环境变量 则可以使用ENV foo bar 因为这是一个 ruby 过程 如果您需要
  • self.tableView.delegate = self Swift

    如果我有一个 UIViewController 并且我在故事板中将 tableView 连接到它 连接 tableview 出口 然后通过连接检查器连接数据源和委托方法 cntrl 拖动到 vc 橙色圆圈图标 我还需要添加self tabl
  • 如何解决没有 xargs -d 的 MacOS X 问题?

    我有以下命令 xargs d n n 8 bash c phpcs element PSR2 1 2 3 4 5 6 7 8 gt 2 2 gt dev null 如果我在 Linux 中运行此命令 它会起作用 如果我尝试在 Mac OSX
  • Apiary:是否可以记录 JSON 响应字段是什么?

    我想记录实际的 JSON 字段本身代表什么 我已经记录了 GET 语句和参数 但这并不能提供给用户的完整文档 那么 在下面的示例中 我将如何添加有关 OtherFields 的注释 支持吗 或者我是否需要在其他地方制作一份配套文档 View
  • GStreamer:将虚拟音轨添加到接收的 rtp 流中

    我正在使用以下命令从 Raspberry 相机启动 RTP 流 raspivid n vf fl t 0 w 640 h 480 b 1200000 fps 20 pf baseline o gst launch 1 0 v fdsrc h
  • 获取 Span 文本的值

    我有一个跨度class span 和一个隐藏字段class dropdown The span文本发生变化 我需要抓取文本并将其设置为隐藏字段值的值 然后我将使用 php 我已经有了 并使用隐藏字段的名称通过电子邮件将文本发送给我 我该怎么
  • 在 .app 运行时触发脚本(AppleScript 或 JXA)?

    我有一个小型计算机实验室 供学生在无人监督的情况下使用 并在网络上连接了打印机 我正在尝试实现一个简单的脚本添加警报对话框 其中包含有关打印机的所有规则 当他们从任意数量的不同应用程序中选择打印时 我需要弹出这些规则 我正在尝试将脚本直接附
  • 禁用 JButton 的空格键触发单击

    JButton 认为按空格键与单击 JButton 相同 假设 JButton 具有焦点 我在这里假设 有没有办法关闭这种行为 让他们忽略按空格键 另外 更一般地说 是否有一种技术可以做到这一点AbstractButtons 您可以通过执行
  • 删除默认构造函数仍然是微不足道的?

    查看标准中普通默认构造函数的定义 如果默认构造函数不是用户提供的并且满足以下条件 则它是微不足道的 它的类没有虚函数 10 3 也没有虚基类 10 1 并且 其类的非静态数据成员没有大括号或等于初始化程序 并且 其类的所有直接基类都有简单的
  • 如果用户有 cookie javascript 如何重定向用户

    我需要知道当用户第一次使用 javascript 访问该页面时如何为他们提供 cookie 然后我需要 cookie 在 1 小时内过期 如果 cookie 仍然存在并且他们尝试在 1 小时结束之前访问该页面 那么它会重定向他们 相关解决方
  • HTML5 视频的图像占位符备用

    我使用以下代码在页面上实现 HTML5 视频
  • .NET System.Diagnostics.Stopwatch 问题(返回值太低)

    在我的计算机上 秒表返回的值太低 例如 当我指定时为 200 毫秒Thread Sleep 1000 该程序应该等待 1 秒 我也测试过ManualResetEvent WaitOne 1000 并得到相同的结果 框架 2 0 和 3 0
  • SQL 中的排除语句

    如何使用SQL语句从SQL数据库中排除数据 我的情况是 我有一个用户登录到他们的个人资料页面 他们可以在其中与人交友 我想显示在 SQL 数据库中找到的除他们自己之外的所有用户 也许只是 SELECT FROM Users WHERE Us
  • 如何创建一个迭代器来生成项目,其中没有项目的单个字符在 python 中表示超过 n 次?

    我创建了一个脚本 它使用以下代码来迭代 sCharacters 字符串中的所有字符组合 sCharacters abcdefghijklmnopqrstuvwxyz0123456789 iKeyLength len sCharacters
  • 如果 PostgreSQL 上不存在如何添加列?

    问题很简单 如何添加列x到餐桌y 但仅当x列不存在 我找到了唯一的解决方案here https stackoverflow com questions 9991043 how can i test if a column exists in
  • nginx代理通过Node,SSL?

    我的 nginx 服务器实际上是用一个简单的方法代理我的节点后端 监听端口 3000 location api proxy pass http upstream 1 其中upstream 1是我在nginx conf中定义的节点集群 在端口
  • 什么是跟踪分支?

    有人可以解释一下适用于 git 的 跟踪分支 吗 这是来自的定义git scm com https git scm com book en v2 Git Branching Remote Branches Git 中的 跟踪分支 是本地分支
  • 继承:选择继承哪些基类方法[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有课Base并想写一个类Derive它仅继承了部分成员函数Base 有什么方便的方法可以做到这一点吗 例如 class Base void
  • 在 C# 中访问简单的布尔标志时,是否需要锁定或标记为易失性?

    假设您有一个在后台线程上运行的简单操作 您希望提供一种方法来取消此操作 因此您创建一个布尔标志 并从取消按钮的单击事件处理程序将其设置为 true private bool cancelled private void CancelButt