2016-12-07 2 views
0

У меня очень странная проблема, еще в один день. Я начал разрабатывать приложение, которое выполняет некоторую синхронизацию продуктов. Загрузка списка продуктов должна была быть асинхронной, чтобы не блокировать GUI во время обновлений. Я выбрал для выполнения этой задачи фонового работника, все работало как следует, в случае ошибок я обработал их в RunWorkerCompleted.BackgroundWorker остановился, чтобы передать исключение в RunWorkerCompleted

Недавно меня попросили сделать некоторые улучшения, но теперь я столкнуться с большой проблемой, исключением из внутри DoWork метода одного из фоновых рабочих выбрасываются внутри этого метода, а не от RunWorkerCompleted.

Возможно, обновление .NET Framework изменилось backgroundWorker поведение, о котором я не знаю? Я действительно не отслеживаю версию фреймворка, до сих пор все работало нормально. Если это важно, я использую SharpDevelop 5.1 как IDE.

Я прошел через несколько веб-поисков по проблеме, и любое из решений, похоже, не решает мою проблему, или, может быть, я применяю ее неправильно? так что есть вещи, которые я пробовал

  • Запуск приложения в режиме неотладочной - ничего не меняет
  • Ловля исключения внутри DoWork и отмена фона рабочего - тогда работник получил завершено, но ошибка не была передана RunWorkerCompleted
  • избавлении от e.Result.ToString() изнутри RunWorkerCompleted, как это было ломать вещи - для меня это работало в начале и не было ничего плохого, удалив его или оставить его в качестве это не имеет никакого значения

Я не знаю, что изменилось, и понятия не имеют, как это исправить, кто-нибудь имеет какие-либо предложения, как для того, как решить мою проблему и сделать 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.Результат.ToString() внутри RunWorkerCompleted и более точно в состоянии ошибки обработки из RunWorkerCompleted. Это не меняет того факта, что с 2014 года, когда я начал свой проект, все работало безупречно с этим точным кодом. Удаление e.Result.ToString() из кода исправляет проблему. Он по-прежнему остается для меня загадкой, почему это происходит именно так и почему RunWorkerCompleted код вызывает исключение метания по DoWork

+0

Ответ находится в посте Мика. Его ответ - реальное решение этой проблемы: доступ к e.Result, когда e.Error! = Null вызывает исключение TargetInvocationException, как он объяснил – almulo

2

Я побежал код, я бы предполагаю, что BackgroundWorker работает, как ожидалось.

Есть проблемы с вашим bgwProductListUpdaterRunWorkerCompleted, вы можете ожидать, что он вызовет исключение TargetInvocationException, когда исключение будет отправлено в bgwProductListUpdaterDoWork.

Как задокументировано here, вы можете ожидать, что TargetInvocationException получает доступ к результату, когда Ошибка! = Null и InvalidOperationException, получающий результат при отмене, является истинным. Вы должны проверить оба перед доступом к свойству Result внутри bgwProductListUpdaterRunWorkerCompleted.

При обращении с ошибками вы должны быть особенно осторожны, поскольку исключения, возникающие при обработке исключения, могут вызвать много путаницы.

Смежные вопросы