2016-12-07 65 views
0

我有一個非常奇怪的問題,早在我開始開發應用程序時就會執行一些產品同步。產品列表的下載必須是異步的,以便在更新期間不鎖定GUI。我確實選擇了做這個任務的後臺工作人員,所有工作都應該如此,以防我在RunWorkerCompleted中處理錯誤。BackgroundWorker停止將異常傳遞到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 
    } 

回答

0

顯然我在測試相關性e.Result。的ToString()內RunWorkerCompleted,更精確的錯誤處理條件的RunWorkerCompleted。這並沒有改變這個事實,即從2014年開始我的項目開始,這些確切的代碼完美無缺地工作。刪除e.Result.ToString() from code fixes problem。它仍然是謎我爲什麼會發生這樣的,爲什麼RunWorkerCompleted代碼導致由DoWork的

+0

答案是米克的帖子引發異常。他的回答是這個問題的真正解決方案:當e.Error!= null拋出TargetInvocationException時,訪問e.Result,正如他解釋的 – almulo

2

我跑你的代碼,我建議BackgroundWorker的工作正常的代碼。

您的bgwProductListUpdaterRunWorkerCompleted有問題,您可以期望它在bgwProductListUpdaterDoWork中拋出異常時引發TargetInvocationException。

如文檔here所示,當Error!= null時,您可以期望TargetInvocationException訪問結果,並且當Cancelled爲true時,InvalidOperationException訪問結果。您應該在訪問bgwProductListUpdaterRunWorkerCompleted中的Result屬性前檢查兩者。

在處理錯誤時,應該特別小心,因爲在處理異常期間引發的異常可能會引起很多混淆。

相關問題