【问题标题】:BackgroundWorker stopped to pass exception to RunWorkerCompletedBackgroundWorker 停止向 RunWorkerCompleted 传递异常
【发布时间】:2016-12-07 02:13:32
【问题描述】:

我有一个非常奇怪的问题,前一天我开始开发一些产品同步的应用程序。产品列表的下载必须是异步的,才能在更新期间不锁定 GUI。我确实选择了一个后台工作人员来执行该任务,所有工作都按其应有的方式工作,以防出现错误,我已在 RunWorkerCompleted 中处理了它们。

最近我被要求做一些改进,但现在我确实遇到了一个大问题,来自后台工作人员之一的 DoWork 方法内部的异常是从这个方法中抛出的,而不是从 RunWorkerCompleted

也许一些 NET 框架更新改变了我不知道的 backgroundWorker 行为?我真的不跟踪框架版本,直到现在一切正常。如果它很重要,我会使用 SharpDevelop 5.1 作为 IDE。

我已经通过有关问题的几次网络搜索,但任何解决方案似乎都无法解决我的问题,或者我可能以错误的方式应用它?所以有些事情我已经尝试过

  • 在非调试模式下运行应用程序 - 没有任何变化
  • DoWork 中捕获异常并取消后台工作程序 - 然后工作程序完成但没有错误传递给 RunWorkerCompleted
  • RunWorkerCompleted 内部摆脱 e.Result.ToString(),因为它必须破坏事物 - 对我来说,这在一开始就有效,没有任何问题,删除它或保持原样都没有区别

我不知道发生了什么变化,也不知道如何解决它,是否有人对如何解决我的问题并让 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
    }

【问题讨论】:

    标签: c# .net exception backgroundworker


    【解决方案1】:

    我运行了您的代码,我建议 BackgroundWorker 正在按预期工作。

    您的 bgwProductListUpdaterRunWorkerCompleted 存在问题,当 bgwProductListUpdaterDoWork 中引发异常时,您可以预期它会引发 TargetInvocationException。

    正如 here 所记录的,当 Error != null 和 InvalidOperationException 在 Canceled 为 true 时访问 Result 时,您可以期待 TargetInvocationException 访问 Result。在访问 bgwProductListUpdaterRunWorkerCompleted 中的 Result 属性之前,您应该检查两者。

    在处理错误时,您应该格外小心,因为在处理异常期间抛出的异常会导致很多混乱。

    【讨论】:

      【解决方案2】:

      显然我在测试e.Result.ToString()RunWorkerCompleted中的相关性时没有集中注意力并犯了错误>,更准确地说是 RunWorkerCompleted 的错误处理条件。这并没有改变这样一个事实,即从 2014 年我开始我的项目时,这个确切的代码可以完美地工作。从代码中删除 e.Result.ToString() 可修复问题。为什么会发生这种情况以及为什么 RunWorkerCompleted 代码会导致 DoWork

      抛出异常,对我来说仍然是个谜

      【讨论】:

      • 答案在 Mick 的帖子中。他的回答是这个问题的真正解决方案:当 e.Error != null 时访问 e.Result 会引发 TargetInvocationException,正如他所解释的那样
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多