【问题标题】:Closures and BackgroundWorker Event Handlers闭包和 BackgroundWorker 事件处理程序
【发布时间】:2011-09-15 21:21:19
【问题描述】:

我定义了一个简单的 BackgroundWorker,它为其 DoWork 和 RunWorkerCompleted 事件处理程序使用闭包,它们分别设置和检查布尔值。简化后的代码(.NET 3.5 中的 C#)如下所示:

    public void SomeMethod()
    {
         BackgroundWorker worker = new BackgroundWorker();

         bool result = false;
         worker.DoWork += new DoWorkEventHandler(
             (sender, e) =>
             {
                 result = LengthyOperation(); 
             });

         worker.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(
             (sender, e) => 
             {
                 AppendRunLog("Result: " + (result ? "PASS" : "FAIL"));
             });

         worker.RunWorkerAsync();
     }

SomeMethod 从主 UI 线程上的 WPF 按钮处理程序调用。

通常这工作得很好,但每隔一段时间我就会收到一个报告,指出操作在应该通过时失败(根据 LengthyOperation 内部生成的日志),即布尔结果在 Completed 处理程序中记录为 false 时操作应该在 DoWork 处理程序中返回 true。

我仔细检查并测试了 LongyOperation 中的代码,以确保其中没有一些细微的错误,并且我相当确信它是干净的。我无法在我的开发环境中重现它。

在设置和读取结果值的方式上是否存在竞争条件?我希望在触发 Completed 事件之前,DoWork 中的赋值操作已经完成。

【问题讨论】:

    标签: c# .net-3.5 closures backgroundworker


    【解决方案1】:

    假设BackgroundWorker 基础架构确保存在适当的内存屏障,我觉得应该没问题。

    您确定您不仅有两个并发操作,而且您同时看到两组日志吗?

    【讨论】:

    • 为了简化示例,我省略了禁用按钮的部分,以便在完成之前无法再次触发操作。日志同意这一点。我有一个将其转换为 .NET 4 的辅助项目,我可能会将 BackgroundWorkers 切换为 Tasks,仅出于学习经验。感谢您的健全性检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多