В приложении WPF у меня есть запланированная задача доступа к базе данных, периодически выполняемый таймером и этой задачей были выполнены в потоке BackgroundWorker.
Когда попытка подключения перестала работать, я повышаю исключение try_catch
конструкция и я хотим обновить Текст строки состояния в потоке UI.
Есть ли в a некоторая конструкция события перед сборкой BackgroundWorker
для реализации этого, чего-то как DoWorkEventHandler
или RunWorkerCompletedEventHandler
, который может использоваться для этого? В противном случае, как сделать это лучше?
Отредактированный (добавил):
Если я хочу обработать исключение внутри RunWorkerCompletedEventHandler
, использование e.Error
параметр, это не работает. В случае, если я оставляю исключение необработанным в BackgroundWorker
поток, приложение держится, и отладчик указывает на строку кода, который является excuted внутри BackgroundWorker
поток, говоря, что: Исключение было не обработано пользовательским кодом.
Так, в этом случае поток не просто останавливается, сигнализируя к RunWorkerCompletedEventHandler
то, что это остановилось с ошибкой, но целое приложение прекращает работать.
Пользовательский интерфейс WPF можно обновить из фонового потока с помощью Dispatcher.BeginInvoke.
Например, если ваш фоновый код был частью Window, вы могли бы обновить TextBlock:
this.Dispatcher.BeginInvoke((Action)(() =>
{
textBlock.Text = "Connection Failed!";
}));
Edit:
Если бы ваш фоновый код был в классе, отличном от вашего Window, вы могли бы создать интерфейс для помощи:
public interface IShowStatus
{
void ShowStatus(string message);
}
Реализуйте интерфейс в вашем окне
public void ShowStatus(string message)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
textBlock.Text = message;
}));
}
В вашем классе с фоновым рабочим создайте свойство для хранения ссылки на интерфейс.
public IShowStatus StatusDisplay { get; set; }
В вашем классе Window инициализируйте фоновый класс.
public void InitBackground()
{
BackgroundClass background = new BackgroundClass();
background.StatusDisplay = this;
...
Наконец, в своем фоновом потоке вы можете сказать:
StatusDisplay.ShowStatus("Connection Failed!");
RunWorkerCompletedEventArgs e
из RunWorkerCompletedEventHandler
содержит свойство Ошибка
, это исключение типа. Если во время работы фонового потока исключение не возникло, то значение prpery равно null. В противном случае он содержит произошедшую ошибку.
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Exception exceptionThrowDuringDoWorkEventHandler = e.Error;
}
Задайте для свойства WorkerReportsProgress фонового рабочего значения true , затем добавьте обработчик событий для события ProgressChanged . В следующем коде я также добавил обработчик событий для Form.Load.
Теперь попробуйте следующий код:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
MessageBox.Show(e.UserState.ToString());
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
//some code that throws an exception
throw new NotImplementedException();
}
catch (Exception ex)
{
backgroundWorker1.ReportProgress(0/*percent of progress*/, ex);
}
}
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}