7

我的一个应用程序中的后台工作人员遇到了一个非常奇怪的问题。我最近对它进行了一些 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 已被跳过。再次,这在我的 PC 上完美运行,但在其他人上不管我如何发布它。

感谢您的帮助

4

3 回答 3

19

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

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

您可能会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 事件。

于 2011-11-24T08:21:25.377 回答
0

Jay Riggs 的回答是正确的,但我只是想补充一点,DoWork 中某些问题引起的异常甚至不会被try...catchinDoWork捕获,这让我很惊讶。

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

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

于 2020-02-14T15:32:03.230 回答
0

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

于 2018-12-27T18:43:03.010 回答