我有一个非常奇怪的问题,在一天之内我开始开发一些产品同步的应用程序。下载产品列表必须是异步的,以便在更新期间不锁定GUI。我确实选择了后台工作人员执行该任务,所有工作都应该正常工作,如果出现错误,我已经在 RunWorkerCompleted 中处理了它们。
最近我被要求做一些改进,但现在我确实遇到了一个大问题,其中一个后台工作者的 DoWork 方法的异常是从这个方法中抛出而不是来自 RunWorkerCompleted
也许某些.NET框架更新改变了我不了解的 backgroundWorker 行为?我真的没有跟踪框架版本,直到现在一切正常。如果它很重要,我使用SharpDevelop 5.1作为IDE。
我经历了几次关于问题的网络搜索,而且任何解决方案似乎都无法解决我的问题,或者我可能错误地应用它?所以我尝试过的东西
我不知道发生了什么变化,并且不知道如何解决它,是否有人对如何解决我的问题有任何建议,并使 BackgroundWorker 以错误的方式传递错误。
这是导致问题的代码
public string WEB_JSON_RAW_DATA {get;set;}
bgwProductListUpdater = new BackgroundWorker();
bgwProductListUpdater.WorkerReportsProgress = true;
bgwProductListUpdater.DoWork += new DoWorkEventHandler(this.bgwProductListUpdaterDoWork);
bgwProductListUpdater.ProgressChanged += new ProgressChangedEventHandler(this.bgwProductListUpdaterProgressChanged);
bgwProductListUpdater.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgwProductListUpdaterRunWorkerCompleted);
void bgwProductListUpdaterDoWork(
object sender,
System.ComponentModel.DoWorkEventArgs e)
{
//source of exception
WEB_JSON_RAW_DATA += (string)ApiClient.Get("/admin/product.json?GET_LIST");
//rest of json processing
}
void bgwProductListUpdaterProgressChanged(
object sender,
System.ComponentModel.ProgressChangedEventArgs e)
{
//this method is empty, it was intended to be used but then no need of progress repporting was needed
//it was all the time in my code so i do paste it as well
}
void bgwProductListUpdaterRunWorkerCompleted(
object sender,
System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if(e.Error != null)
{
string ExtraErrorData = "";
if (e.Error.Data.Count > 0)
{
foreach (DictionaryEntry de in e.Error.Data)
ExtraErrorData += string.Format(
" Key: {0,-20} Value: {1}",
"'" + de.Key.ToString() + "'",
de.Value) + Environment.NewLine;
}
Common.LogWindow.Log(string.Format("{0} - Downloading product list - {1}",ShortName,
Environment.NewLine + e.Error.Message +
Environment.NewLine + ExtraErrorData +
Environment.NewLine + e.Result.ToString()));
ShopHasErrors = true;
}
//do rest of finalizing
}
答案 0 :(得分:2)
我运行了你的代码,我建议BackgroundWorker按预期工作。
bgwProductListUpdaterRunWorkerCompleted存在问题,当bgwProductListUpdaterDoWork中抛出异常时,您可以预期它会抛出TargetInvocationException。
如记录here,您可以预期TargetInvocationException在Error!= null时访问Result,而InvalidOperationException在Canceled为true时访问Result。您应该在访问bgwProductListUpdaterRunWorkerCompleted中的Result属性之前检查两者。
在处理错误时,您应该格外小心,因为在处理异常期间抛出的异常会导致很多混淆。
答案 1 :(得分:0)
显然,在测试 RunWorkerCompleted <内的 e.Result.ToString() 的相关性时,我没有集中注意力并犯了错误/ em> ,更确切地说是 RunWorkerCompleted 的错误处理条件。这并没有改变这一事实,从2014年开始我的项目开始,这些确切的代码完美无缺。从代码中删除 e.Result.ToString() 修复了问题。我仍然不知道为什么它会以这种方式发生以及为什么 RunWorkerCompleted 代码导致抛出异常 DoWork