【问题标题】:Define backgroundworker's RunWorkerCompleted with an anonymous method?用匿名方法定义backgroundworker的RunWorkerCompleted?
【发布时间】:2009-02-27 11:03:06
【问题描述】:

我希望我用了正确的术语

我的目标是这样的(我意识到它不会那样工作):

private bool someBool = false;

BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(DoLengthyTask);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
    ()=>
        {
            someBool = true;
            Logger.Info("Finished");
        }
)

重要的部分是 RunWorkerCompletedEventHandler 被定义在原始调用者的范围内并且可以访问调用者的变量。

这可能吗?它会在 someBool 上产生可能的竞争条件吗?

【问题讨论】:

  • 还有什么可以访问布尔值?这对于了解可能的竞争条件至关重要......
  • 主线程中的东西会访问布尔值。在这个(虚构的)示例中,记录器中的某一行可能会在以后添加。

标签: c# multithreading lambda


【解决方案1】:

它在您的示例中不起作用,因为完整的委托应该接收 2 个参数:

private bool someBool = false;

BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(DoLengthyTask);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        (sender, e)=>
                {
                        someBool = true;
                        Logger.Info("Finished");
                }
)

【讨论】:

  • 虽然是真的,但我不确定这是否能回答实际问题...
  • 现在只剩下竞争条件问题了。
【解决方案2】:

这完全取决于布尔值的其他用途。

特别是,它 bool 真的是一个字段(正如“私人”所暗示的那样),还是一个变量?有一点不同,您可以将字段标记为volatile(但不能标记为变量)。

但是,我的直觉是,您应该使用诸如 Monitor 之类的同步,也许使用脉冲等 - 或诸如 ManualResetEvent 之类的门。

如果没有同步或volatileit is possible,另一个线程看不到变量的变化——但如果没有另一半代码,我们真的不能说更多......

【讨论】:

猜你喜欢
  • 2011-01-05
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多