C#后台工作者在除了我的电脑之外的任何电脑上都无法触发“dowork”事件

7
我在我的一个应用程序中使用的后台工作线程遇到了一些奇怪的问题。最近我改善了一些GUI问题,但现在当其他电脑上的人运行.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事件,并显然针对索引传递了一个错误,因为列表还没有被填充,因为执行此操作的函数已被跳过。再次强调,无论我如何将其发布给其他人,它在我的个人电脑上都能完美运行。感谢您的任何帮助。

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

19

我猜测你的DoWork方法抛出了异常,因此调用了RunWorkerCompleted方法。

请注意,在后台工作器(BGW)的DoWork方法中抛出的异常将不会在RunWorkerCompleted方法的try...catch块中捕获;相反,常规做法是检查RunWorkerCompletedRunWorkerCompletedEventArgs参数中的Error属性是否为空。如果不为空,则表示出现了异常。

您可以像这样重新编写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事件,了解更多信息并获取比我更好的示例。


谢谢,这帮助我找到了问题所在。我的一个 DLL 文件不知怎么出了问题,重建它后现在它又可以正常工作了。非常感谢! - Brandonm
今天我也遇到了这个问题,记录异常信息结果正是我需要解决问题的关键,很奇怪,原来是因为我们客户端电脑上没有正确版本的 DLL 文件。 - Jrud
这对我有用。我的后台工作程序嵌入在MS Excel Add In中。在客户修复他们的Excel之前,我无法看到e.Error结果日志。 - Jason P Sallinger

0
Jay Riggs的回答是正确的,但我想补充一点,由DoWork引起的异常甚至不会被DoWork中的try...catch捕获,这对我来说很神奇。
我遇到了这样一种情况,我的DoWork例程使用了第三方库,该库又使用了另一个缺失的库。当我的应用程序调用DoWork时,即使库没有立即使用,即使整个方法都包含在try...catch中,它也会在方法外部失败,并调用RunWorkerCompleted,就好像一切都很顺利。因此,后台作业什么也没做,但也没有抛出异常,它只是将异常静默地放在Error属性中,而我忽略了它,因为我从未知道它的存在。这需要非常仔细的调试才能发现。
我的经验教训是,您始终需要检查RunWorkerCompleted中的错误,并且这是非常反直觉的行为。如果没有Jay Riggs的答案,我无法想象要花多长时间才能找出问题所在。

0

对我来说,问题出在我的主项目已签名,但我引入的新 DLL 没有进行签名。很奇怪,因为我从未收到过警告或错误提示,而且项目编译也成功了。只是在调试中,background_dowork() 根本没有被触发。一旦我给 DLL 添加了签名证书,它就可以正常启动 backgroundworker 了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接