【问题标题】:BackgroundWorker Return A Value?BackgroundWorker 返回一个值?
【发布时间】:2011-03-07 19:31:25
【问题描述】:

以下代码将 1 到 100 的数字相加并返回总和。我要做的是在后台工作程序中运行计算并返回一个值。这样做的问题是 returnValue 在 DoWork 完成之前返回。如何在返回值之前等待我的后台工作人员完成? (我似乎无法将回报放入我的 DoWork...)

double returnValue = 0;

var b = new BackgroundWorker();
b.DoWork += new DoWorkEventHandler(
    delegate(object sender, DoWorkEventArgs e) {
        for(int i=0;i<100;i++){
            returnValue += (i+1);
        }
    }
);

b.RunWorkerAsync();
return returnValue;

附录:在同一线程上发送消息泵而不是在后台工作人员上运行会更好吗?

另外,这只是示例代码,我的实际代码需要一分钟以上才能完成。

【问题讨论】:

标签: c# backgroundworker


【解决方案1】:

订阅RunWorkerCompleted 事件。该事件包含后台操作的返回值。

当然,该值将从DoWorkEventHandler 内部返回,如下所示:

b.DoWork += new DoWorkEventHandler(
    delegate(object sender, DoWorkEventArgs e) {
        double returnValue = 0;
        for(int i=0;i<100;i++){
            returnValue += (i+1);
        }
        e.Result = returnValue;
    }
);

【讨论】:

  • 是的,这很好用。我也喜欢返回值可以是对象或结构。
  • not working.error DoWorkEventHandler 返回 void,return 关键字后面不能跟对象
  • @BeeLabeille 似乎我把“return”写错了,尽管这么多年后我不知道我当时在想什么。反正设置e.Result是正确的。
  • @Jon 是的,你是对的。经过昨天的一番挖掘,我最终意识到我需要使用的是 Result 属性,因此我建议的答案
【解决方案2】:

我在这里没有真正看到问题,但我认为您正在寻找的是名为RunWorkerCompleted 的事件。当DoWork 代表完成时,就会出现这种情况。如果这不是您想要的,我认为您需要重新表述您的问题。

【讨论】:

    【解决方案3】:

    我有一个示例:here 也许它可以帮助你:-)

    另外,这只是示例代码,我的实际代码需要一分钟以上才能完成。

    这可能是异步启动的影响。您可以告诉后台工作人员何时开始或只说开始。如果你没有明确说他应该现在开始,他会在 c# 认为现在是开始的好时机时开始:-)

    【讨论】:

      【解决方案4】:

      如果您像我一样因为 DoWorkEventHandler 返回 void 而无法使用已接受的答案,那么下面的代码可能会有所帮助。

      double returnValue = 0;
      var b = new BackgroundWorker();
      b.DoWork += PerformJob;
      b.RunWorkerCompleted += JobDone;
      
      private void PerformJob(object sender, DoWorkEventArgs args)
      {
          // Pre-Processing: for-loop to increment returnValue
          /*
          ** DoWorkEventArgs has a 'Result' object with the following description
          ** Summary: Gets or sets a value that represents the result of an asynchronous operation.
          ** Returns: An System.Object representing the result of an asynchronous operation.
          */
          args.Result = returnValue;
      }
      
      private void JobDone(object sender, RunWorkerCompletedEventArgs args)
      {
          //RunWorkerCompletedEventArgs also has a 'Result' object like DoWorkEventArgs
          double updatedReturnValue = (double)args.Result;
      
          // Post-processing: e.g. use updatedReturnValue to update a text block, show a message box etc.
      }
      

      【讨论】:

      • 请注意,现在接受的答案已经过编辑,以反映使用“结果”属性而不是“返回”语句
      【解决方案5】:

      您正在尝试使用它BAD 的BackgroundWorker 进行同步操作。但如果必须,您可以使用 IsBusy 标志。

      double returnValue = 0;
      
      var b = new BackgroundWorker();
      b.DoWork += new DoWorkEventHandler(
          delegate(object sender, DoWorkEventArgs e) {
              for(int i=0;i<100;i++){
                  returnValue += (i+1);
              }
          }
      );
      
      b.RunWorkerAsync();
      while(b.IsBusy){
        Application.DoEvents();
      }
      return returnValue;
      

      【讨论】:

      • 这有点违背了 BackgroundWorker 的目的。
      • @Bryan 完全正确。但如果他必须等待 BackgroundWorker 完成,那么为什么要使用 BackgroundWorker ?
      • 消息泵会更好吗?
      • @sooprise 喜欢Application.DoEvents(); 吗?确定
      • 调用 Application.DoEvents 几乎总是一个坏主意。 msdn 试图澄清这一点,但恕我直言,它并没有充分强调这是一个多么糟糕的想法。 msdn.microsoft.com/en-us/library/…
      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      相关资源
      最近更新 更多