2016-12-07 4 views
0

제가 제품을 동기화하는 응용 프로그램을 개발하기 시작한 이래로 매우 이상한 문제가 있습니다. 제품 목록의 다운로드는 업데이트 중에 GUI를 잠그지 않는 비동기식이어야했습니다. 나는이 작업을 배경 작업자로 선택했다. 오류가 발생할 경우 모두 처리해야한다. RunWorkerCompleted. BackgroundWorker가 RunWorkerCompleted에 예외를 전달하지 못했습니다.

는 최근에 나는 약간의 개선을하도록 요청했지만 지금은, 배경 노동자 중 하나의 DoWork 방법 내부에서 예외가이 방법에서가 아니라 에서에서 던져 큰 문제가 발생을 RunWorkerCompleted 않습니다.

일부 NET 프레임 워크 업데이트가 변경된 것 같습니다. backgroundWorker 내가 모르는 동작입니까? 프레임 워크 버전을 추적하지 못하고 있습니다. 이제는 정상적으로 작동합니다. 중요한 경우 SharpDevelop 5.1을 IDE로 사용합니다.

나는 여러 웹 검색을 통해 문제를 해결해 왔으며 해결책 중 하나가 내 문제를 해결하지 못하거나 잘못된 방식으로 적용하고있는 것처럼 보입니까? 그래서 비 디버그 모드에서 응용 프로그램을 실행

  • 을 시도한 일이있다 - 아무것도
  • DoWork 내부 예외를 잡기 및 배경 노동자를 취소 변경되지 않습니다 - 후 근로자가 완료되었다하지만 오류가 RunWorkerCompleted에 전달되지 않았다 이것은 처음에 일을 나를 위해 아무것도를 제거하거나로 떠나, 잘못 없다 - 그것은 일을 중단했다으로
  • 을 RunWorkerCompleted 내부에서 e.Result.ToString() 제거하기 내가 모르는

변경 무슨 차이가 없으며, 그것을 해결하는 방법을 단서가 없다, 방법을 오류 통과 BackgroundWorker에를 내 문제를 해결하고 을 만드는 방법에 관해서는 사람이 어떤 제안을 가지고 수행되었다 그것은해야한다. 여기

내가 예상대로 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.을 RunWorkerCompleted의 ToString() 내부은 더 정확하게 에러 처리 상태를 RunWorkerCompleted. 2014 년부터 프로젝트를 시작할 때이 정확한 코드로 완벽하게 작동한다는 사실은 변함이 없습니다. 제거 e.Result.ToString() 코드 수정 문제. 그것이 이런 식으로 발생하고 이 RunWorkerCompleted 이유 코드가 DoWork

+0

대답은 믹의 게시물에 의해 예외를 던지는 발생 이유는 아직 나에게 신비에 남아있다. 그의 대답은이 문제에 대한 진정한 해결책이다 : e.Error! = null이 TargetInvocationException을 throw 할 때 e.Result에 액세스 함 – almulo

2

원인 코드입니다.

bgwProductListUpdaterRunWorkerCompleted에 문제가 있습니다. bgwProductListUpdaterDoWork 내에서 예외가 발생하면 TargetInvocationException을 throw 할 수 있습니다.

문서화 된 here과 같이, Error! = null 일 때 Result에 액세스하고 Canceled가 true 일 때 Result에 액세스하는 InvalidOperationException을 액세스하는 TargetInvocationException이 발생할 수 있습니다. bgwProductListUpdaterRunWorkerCompleted 내부의 Result 속성에 액세스하기 전에 두 가지를 모두 확인해야합니다.

오류를 처리 할 때 예외 처리 중에 발생하는 예외는 많은 혼란을 야기 할 수 있으므로주의해야합니다.