多线程中 volatile 变量的值不会改变

2024-02-28

我有一个在后台运行的 winform 应用程序BackgroundWorker它有一个无限循环,每小时执行一些事情。我的用户界面Form类是这样的:

public partial class frmAutoScript : Form
{
    private volatile bool _isDownloading = false;
    private bool IsDownloading { get { return this._isDownloading; } set { this._isDownloading = value; } }

    public frmAutoScript()
    {
        InitializeComponent();
        this.RunAutoSynchronization();
    }

    private void RunAutoSynchronization()
    {
        bool isDownloading = this.IsDownloading;

        BackgroundWorker bgwDownloader = new BackgroundWorker();
        bgwDownloader.WorkerReportsProgress = true;
        bgwDownloader.ProgressChanged += (sndr, evnt) =>
        {
            if (evnt.ProgressPercentage == 2)
                isDownloading = this.IsDownloading;
            else
            {
                this.IsDownloading = evnt.ProgressPercentage == 1;
                isDownloading = this.IsDownloading;
            }
        };
        bgwDownloader.DoWork += (sndr, evnt) =>
            {
                while (true)
                {
                    if (DateTime.Now.Hour == 16 &&
                        DateTime.Now.Minute == 0)
                    {
                        try
                        {
                            bgwDownloader.ReportProgress(2);
                            if (!isDownloading)
                            {
                                bgwDownloader.ReportProgress(1);
                                new Downloader().Download();
                            }
                            bgwDownloader.ReportProgress(0);
                        }
                        catch { }
                    }

                    System.Threading.Thread.Sleep(60000);
                }
            };
        bgwDownloader.RunWorkerAsync();
    }
}

并在那frmAutoScript,我还有一个名为btnDownload单击时,它将下载并更改volatile多变的_isDownloading。按钮的事件是这样的:

private void btnDownload_Click(object sender, EventArgs e)
{
    if (IsDownloading)
        MessageBox.Show("A download is currently ongoing. Please wait for the download to finish.",
            "Force Download", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    else
    {
        this.IsDownloading = true;
        BackgroundWorker bgwDownloader = new BackgroundWorker();
        bgwDownloader.DoWork += (sndr, evnt) =>
        {
            try
            {
                new Downloader().Download();
            }
            catch(Exception ex)
            {
                MessageBox.Show("An error occur during download. Please contact your system administrator.\n Exception: " +
                    ex.GetType().ToString() + "\nError Message:\n" + ex.Message + " Stack Trace:\n" + ex.StackTrace, "Download Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        };
        bgwDownloader.RunWorkerCompleted += (sndr, evnt) =>
        {
            this.IsDownloading = false;
        };
        bgwDownloader.RunWorkerAsync();
    }
}

但是当我点击按钮时btnDownload_isDownloading被设定为true,当系统时间达到4:00 PM, the new Downloader().Download();即使再次执行_isDownloading设置为 true。为什么会这样?

我的代码是C#,框架4,项目是winforms,在Visual Studio 2010 Pro中构建。


您的代码没有针对volatile字段 - 它正在测试isDownloading, which looks就像“本地”,但是(因为它被捕获)实际上是常规的(非volatile) 场地。因此:要么使用某种内存屏障,要么强制其成为易失性读取。或者更简单地说:摆脱isDownloading 完全地,并对照属性进行检查。

顺便说一句,缓存破坏属性volatile are not关键字的意图,而是:结果。它会起作用,但是亲自我建议编写代码来工作按意图而不是通过结果,也许使用一个简单的lock或者类似的东西Interlocked.

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

多线程中 volatile 变量的值不会改变 的相关文章

随机推荐

  • “Office 2010 加载项:图标库” - 如何从后台选项卡中提取图标 (docx)

    我下载了 Office 2010 加载项 图标库 https www microsoft com en in download confirmation aspx id 21103 这是一个 docx 文件 有两个包含图标的后台选项卡 如何
  • 在c#中将bool表达式转换为char

    当我遇到如下问题时 我通过了 NET 测验 Char ch Convert ToChar a e c a 在控制台中我们可以看到输出ch变量是g 有人可以描述发生了什么吗 谢谢 是二元或运算符 a binary representation
  • 将重复值复制粘贴到大型 Excel 文件的列中

    我遇到了一个问题 希望得到一些帮助 这是我现在正在处理的内容 我想要的是 B C 和 D 列复制到其下面的空白行 直到它到达新客户端 如下所示 非常感谢任何和所有的帮助 Thanks 非VBA解决方案 Select entire range
  • 使用 jQuery 按住 Shift + 鼠标悬停

    我试图检测当光标移动到特定元素上时是否按下了 Shift 键 该函数会触发 但仅after我首先单击另一个元素 有什么方法可以解决这个问题吗 我尝试将焦点设置为文档和元素 并尝试创建伪单击功能 但到目前为止没有任何效果 例如 以下代码仅在我
  • OpenCL clGetPlatformIDs 异常

    我使用此包安装附带的示例中的 HelloWorld 示例 AMD 套件 http developer amd com tools and sdks heterogeneous computing amd accelerated parall
  • SQL 调用临时表中的最大行数

    在临时表中只有两列可用 我想获取每次加载的最新ID 如下图所示 我已经尝试过 但它没有给我我需要的答案 select max rn plus 1 a load a id from select a load a id ROW NUMBER
  • 交互式 lua:命令行参数

    我想做 lua prog lua arg1 arg2 从命令行 在prog lua里面 我想说 比如 print arg1 arg2 n Lua 似乎没有 argv 1 等 而且我见过的处理命令行参数的方法似乎不成熟和 或麻烦 我错过了什么
  • 在 Express 中使用“jade”模板引擎时渲染“html”

    你如何渲染一个html文件 同时保持模板引擎为jade app set view engine jade 是我将模板引擎设置为jade我想做一些类似的事情 app get world function req res res render
  • Android:ScrollView 内的 Horizo​​ntalScrollView

    我有多个水平滚动视图里面一个滚动视图 水平滚动一点也不流畅 我必须几乎完全水平滚动才能滚动才能工作 有没有一个简单的修复方法可以调整这个 谢谢 您可以将 Recycler 视图与交错布局管理器一起使用 StaggeredGridLayout
  • 如何为 TFS 上的 dockerized F# Expecto 测试配置 CI

    我有一些码头化的由 Expecto 和 fscheck 框架编写的 F 测试 作为 dotnet 核心独立可执行文件 如何在 Team Foundation Server 上配置持续集成以运行它们并在每次运行后获取相应的报告 如果您的意思是
  • Play Framework:合并多模块项目中的多个全局对象

    我正在使用 Play 2 3 和 Java 8 构建一个多模块项目 根应用程序和每个模块都有一个全局对象 但我们如何知道 Play 仅使用根应用程序中的一个全局对象 简化的文件夹结构 root app Global java conf ap
  • SAS 中的“auto.arima”?

    我曾经使用 auto arima 在 R 中运行 arima 模型来识别适合数据的最佳 arima 模型 即使没有它 在 R 中编写一个函数来执行类似的任务也很容易 然而 我这几天google了一下 在SAS中找不到类似的过程 有谁知道SA
  • 在Python中应用PMML预测模型

    Knime 为我生成了PMML http en wikipedia org wiki Predictive Model Markup Language模型 这时候我想把这个模型应用到一个python进程中 这样做的正确方法是什么 更深入 我
  • 在应用程序浏览器中将 Instagram 转义至 Safari

    我的网站中有一个链接 可以重定向到 Instagram 登录以获取一些照片 但该页面无法在 iOS 设备上的 Instagram 应用内浏览器上运行 我的想法是放置一个链接 以便用户可以单击它并重定向到 safari 或默认浏览器中的页面
  • 有没有一种好方法可以让 Map get 和 put 忽略大小写? [复制]

    这个问题在这里已经有答案了 有没有好的方法可以有一个Map
  • 如何使用离线设备捕获地理位置 - cordova

    我正在使用 cordova 开发一个应用程序 并发现需要获取用户的纬度和经度数据 但我的应用程序将离线使用 无需互联网访问 我有两个问题 1 如何检查设备是否启用 GPS 2 如何在没有互联网连接的情况下离线获取纬度和经度 这是可能的 我会
  • 在 React 中设置单选按钮值

    我正在制作一个简单的反应应用程序 其表单具有单选按钮 这里有一个可用的默认数据 例如 const defaultData ContactMode 3 ContactMode 2 ContactMode 2 要求 gt 需要迭代这个defau
  • Tensorflow:“GraphDef 不能大于 2GB。”分配变量后保存模型时出错

    我想用一个预训练的模型来热启动另一个有一点差异的模型 简而言之 我创建一个新模型 并使用预训练的模型权重分配具有相同名称的变量 但是 在保存模型时 出现错误 Traceback most recent call last File tf t
  • Android 应用程序在发布中崩溃,但在调试 NullPointerException 中不会崩溃

    由于从我正在使用的 API 返回的数据发生了更改 我最近更改了 2 行代码作为解决方法 现在 当使用发布的 apk 和 aab 时 应用程序崩溃 但是 当我通过 API 27 上的 Android 模拟器使用该应用程序并将 API 27 设
  • 多线程中 volatile 变量的值不会改变

    我有一个在后台运行的 winform 应用程序BackgroundWorker它有一个无限循环 每小时执行一些事情 我的用户界面Form类是这样的 public partial class frmAutoScript Form privat