c#后台工作器不触发dowork事件在任何pc上除了我自己的
本文关键字:任何 pc 自己的 除了我 事件 dowork 工作 后台 | 更新日期: 2023-09-27 18:15:40
我在一个应用程序中遇到了一个非常奇怪的后台工作人员问题。我最近对它进行了一些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事件,并为索引传递一个错误,因为列表还没有被填充,因为函数已经跳过了。同样,这在我的电脑上运行得很好,但不管我如何发布它,在其他人身上都不行。
感谢您的帮助
我的猜测是您的DoWork
抛出异常,因此您的RunWorkerCompleted
被调用。
注意,在BGW的DoWork
方法中抛出的异常将不会在try中被捕获…RunWorkerCompleted
捕获量;相反,模式是检查RunWorkerCompleted
的RunWorkerCompletedEventArgs
参数中的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还没有。这很奇怪,因为我从来没有收到警告或错误,项目编译正常。只是background_dowork()在调试中永远不会被击中。一旦我在DLL中添加了签名证书,它就会启动后台工作器。
Jay Riggs的回答是正确的,但我只是想补充一下,由DoWork 中的某些问题引起的异常甚至不会被DoWork
中的try...catch
捕获,这对我来说是惊人的。
我有一个情况,我的DoWork
例程使用了一个第三方库,而这个库又使用了另一个缺失的库。当我的应用程序调用DoWork
时,即使库没有立即使用和,即使整个方法被包装在try...catch
中,它在方法外失败并调用RunWorkerCompleted
,好像一切正常。所以后台工作什么都没做,但也没有抛出异常,它只是悄悄地把异常放在Error
属性中,我忽略了它,因为我从不知道它。这需要一些非常仔细的调试才能发现。
我的结论是你总是需要检查RunWorkerCompleted
中的错误,这是非常违反直觉的行为。如果没有杰伊·里格斯的答案,我无法想象要花多长时间才能弄清楚。