У меня очень странная проблема, еще в один день. Я начал разрабатывать приложение, которое выполняет некоторую синхронизацию продуктов. Загрузка списка продуктов должна была быть асинхронной, чтобы не блокировать 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
}
Ответ находится в посте Мика. Его ответ - реальное решение этой проблемы: доступ к e.Result, когда e.Error! = Null вызывает исключение TargetInvocationException, как он объяснил – almulo