【问题标题】:C# background worker not triggering dowork event on any pc besides my own除了我自己的电脑,C# 后台工作人员不会在任何电脑上触发 dowork 事件
【发布时间】:2011-11-24 08:01:53
【问题描述】:

我的一个应用程序中的后台工作人员遇到了一个非常奇怪的问题。我最近对它进行了一些 GUI 修复,但现在当另一台 PC 上的某人运行 .exe 或安装我的 OneClick 部署时,后台工作人员不会进入 dowork 事件。两个版本之间的逻辑没有改变。我进行了比较,除了添加更多错误日志之外,没有任何改变。

我已经在 dowork 事件中包含了消息框和断点,但它从未在除了我自己的 PC 之外的任何地方进入它。即使我远程调试它也不会进入 DoWork 事件

有什么建议吗?

按钮点击甚至调用 runworkerasync 事件

private void ScanButton_Click_1(object sender, RoutedEventArgs e)
    {

        Scan = new BackgroundWorker();
        Scan.WorkerReportsProgress = true;
        Scan.DoWork += new DoWorkEventHandler(Scan_DoWork);
        Scan.ProgressChanged += new ProgressChangedEventHandler(Scan_ProgressChanged);
        Scan.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Scan_RunWorkerCompleted);
        Scan.RunWorkerAsync();
    }

以下是运行 DoWork 事件的代码。为了简单起见,我删除了它所做的其他功能。它所做的只是运行一个函数,该函数返回一个字符串并将其放在名为 scanresults 的列表中。

private BackgroundWorker Scan;

    public void Scan_DoWork(object sender, DoWorkEventArgs e)
    {

        System.Windows.Forms.MessageBox.Show("Inside the DoWork");

        BackgroundWorker bw = sender as BackgroundWorker;

        float percentageDone = 0.0F;

        ScanResults = new List<string>();

        try
        {

            System.Windows.Forms.MessageBox.Show("Doing first scan check");

            ScanResults.Add(Functions.LocalComputerName());
            percentageDone = ((1 / 1f) * 100f);
            bw.ReportProgress((int)percentageDone);

        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }


public void Scan_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        try
        {
            if (ScanResults.Count == 0)
            {
                System.Windows.Forms.MessageBox.Show("Empty");
                return;
            }
            MachineNameBox.Text = ScanResults[0];
        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }

它完全忽略了dowork事件并进入了runworkercomplete事件并为索引传递了一个错误,显然是因为列表没有被填充,因为函数do被跳过了。再次,这在我的电脑上完美运行,但在其他人上不管我如何发布它。

感谢您的帮助

【问题讨论】:

  • System.Windows.Forms.MessageBox.Show("DoWork 内部");可能无法在 BackgroundWorker 内部工作。在 DoWork 中设置 e.Result 为异常,并检查 e.Result 是否包含 RunWorkerCompleted 事件中的异常。

标签: c# events backgroundworker eventtrigger


【解决方案1】:

我的猜测是你的DoWork 抛出了一个异常,所以你的RunWorkerCompleted 被调用了。

请注意,在 BGW 的 DoWork 方法中抛出的异常不会被 RunWorkerCompleted 中的 try...catch 捕获;相反,该模式是检查RunWorkerCompletedRunWorkerCompletedEventArgs 参数中的Error 属性是否不为空。如果这不为 null,则您有一个异常。

您可以像这样修改您的 RunWorkerCompleted 代码:

public void Scan_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    if (e.Error != null) {
        // You have an exception, which you can examine through the e.Error property.
    } else {
        // No exception in DoWork.
        try {
            if (ScanResults.Count == 0) {
                System.Windows.Forms.MessageBox.Show("Empty");
                return;
            }
            MachineNameBox.Text = ScanResults[0];
        } catch (Exception ex) {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }
}

请参阅BackgroundWorker.RunWorkerCompleted Event 了解更多信息和比我更好的示例。

【讨论】:

  • 感谢您帮助我找到了问题。我的一个 Dll 以某种方式损坏了,重建它,现在它又可以正常工作了。非常感谢!
  • 我今天也遇到了这个问题,结果记录异常消息正是我解决问题所需要的,奇怪的是,这是因为我们没有正确的版本DLL 在我们客户的计算机上。
  • 这对我有用。我的后台工作人员嵌入在 MS Excel 插件中。在我让客户修复他们的 Excel 之前,我看不到 e.Error 结果日志。
【解决方案2】:

对我来说,我的主要项目已签名,而我引入的新 DLL 没有。这很奇怪,因为我从未收到警告或错误,并且项目编译正常。只是 background_dowork() 甚至永远不会在调试中受到影响。一旦我在 DLL 上添加了签名证书,它就可以启动后台工作程序了。

【讨论】:

    【解决方案3】:

    Jay Riggs 的回答是正确的,但我只是想补充一点,DoWork 中某些问题引起的异常甚至不会被 DoWork 中的 try...catch 捕获,它对我来说太棒了。

    我的DoWork 例程使用了第三方库,而该第三方库又使用了另一个缺少的库。当我的应用程序调用 DoWork 时,即使没有立即使用该库,并且即使整个方法都包含在 try...catch 中,它还是失败了在方法之外并调用RunWorkerCompleted,好像一切都很好。所以后台作业什么也没做,但也没有抛出异常,它只是悄悄地将异常放在 Error 属性中,我忽略了它,因为我从来不知道它。这需要一些非常仔细的调试才能发现。

    我的结论是,您总是需要检查 RunWorkerCompleted 中的错误,这是非常违反直觉的行为。如果没有 Jay Riggs 的答案,我无法想象要花多长时间才能弄清楚。

    【讨论】:

      猜你喜欢
      • 2011-01-19
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多