BackgroundWorker є рекомендованим способом запуску трудомісткого завдання на окремому виділеному потоці, залишаючи UI працездатним.
За допомогою BackgroundWorker можна :
- запустити фонову операцію
- забезпечити параметри для фонової операції
- повернути значення з фонової операції
- відмінити фонову операцію
- звітувати прогрес виконання фонової операції
Одні із найважливіших членів цього класу:
Проперті
| CancellationPending | Gets a value indicating whether the application has requested cancellation of a background operation. |
| IsBusy | Gets a value indicating whether the BackgroundWorker is running an asynchronous operation. |
| WorkerReportsProgress | Gets or sets a value indicating whether the BackgroundWorker can report progress updates. |
| WorkerSupportsCancellation | Gets or sets a value indicating whether the BackgroundWorker supports asynchronous cancellation. |
| DoWork | Occurs when RunWorkerAsync is called. |
| ProgressChanged | Occurs when ReportProgress is called. |
| RunWorkerCompleted | Occurs when the background operation has completed, has been canceled, or has raised an exception. |
| CancelAsync | Requests cancellation of a pending background operation. |
| RunWorkerAsync() | Starts execution of a background operation. |
Запуск фонової операції
Метод RunWorkerAsync починає виконання фонового процесу рейзаючи подію DoWork. Код хендлера події DoWork виконується в окремому потоці.
private void StartButton_OnClick(object sender, RoutedEventArgs e){backgroundworker.RunWorkerAsync();}
void backgroundworker_DoWork(object sender, DoWorkEventArgs e){// perform some logic}
public MainWindow(){InitializeComponent();backgroundworker.DoWork += backgroundworker_DoWork;}
Забезпечення параметра для фонової операції
Для фонової операції можливо потрібно буде один або декілька параметрів. Ви можете надати параметр в методі RunWorkerAsync , який буде доступні в якості проперті Argument в хендлері події DoWork.
private void StartButton_OnClick(object sender, RoutedEventArgs e){backgroundworker.RunWorkerAsync(this.IntegerUpDown.Value);}
void backgroundworker_DoWork(object sender, DoWorkEventArgs e){if (e.Argument != null && e.Argument is System.Int32){int number = (int)e.Argument;}}
Відміна фонової операції
Можливо, ви захочете дозволити користувачеві скасувати довготривалу операцію. Щоб це було можливо, спочатку потрібно:
- встановити пропертю WorkerSupportsCancellation , класу BackgroundWorker, в true.
public MainWindow(){InitializeComponent();backgroundworker.WorkerSupportsCancellation = true;backgroundworker.DoWork += backgroundworker_DoWork;}
- визвати метод CancelAsync щоб відмінити фонову операцію. Метод CancelAsync встановлює пропертю CancellationPending класу BackgroundWorker в true.
#region Cancelling the Background Processprivate void CancelButton_OnClick(object sender, RoutedEventArgs e){if (this.backgroundworker.IsBusy){backgroundworker.CancelAsync();}}#endregion
- перевіряти значення проперті CancellationPending в хендлері події DoWork Якщо вона приймає значення True, то встановити пропертю Cancel параметра DoWorkEventArgs в True.
void backgroundworker_DoWork(object sender, DoWorkEventArgs e){if (e.Argument != null && e.Argument is System.Int32){int number = (int)e.Argument;if (number == 1){e.Result = 1;backgroundworker.ReportProgress(100);return;}int factorial = 1;for (int i = 2; i < number+1; i++){if (backgroundworker.CancellationPending){e.Cancel = true;return;}Thread.Sleep(500);factorial = factorial * i;backgroundworker.ReportProgress(i*100 / number);}e.Result = factorial;}}
Повернення значення з фонової операції
Можливо, ви захочете повернути значення з фонової операції, наприклад результат підрахунку. Для цього необхідно :
- встановивши пропертю Result параметра DoWorkEventArgs в хендлері події DoWork.
void backgroundworker_DoWork(object sender, DoWorkEventArgs e){if (e.Argument != null && e.Argument is System.Int32){int number = (int)e.Argument;if (number == 1){e.Result = 1;backgroundworker.ReportProgress(100);return;}int factorial = 1;for (int i = 2; i < number+1; i++){if (backgroundworker.CancellationPending){e.Cancel = true;return;}Thread.Sleep(500);factorial = factorial * i;backgroundworker.ReportProgress(i*100 / number);}e.Result = factorial;}}
- це значення може бути витягнено з проперті Result параметра RunWorkerCompletedEventArgs в хендлері події RunWorkerCompleted.
public MainWindow(){InitializeComponent();backgroundworker.WorkerSupportsCancellation = true;backgroundworker.DoWork += backgroundworker_DoWork;backgroundworker.RunWorkerCompleted += backgroundworker_RunWorkerCompleted;}
#region Returning a Value from the Processvoid backgroundworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){if (e.Cancelled){this.ShowResultTextblock.Text = "Operation was canceled !";this.Progressbar.Value = 0;}else{this.ShowResultTextblock.Text = String.Format("Factorial is {0} ", e.Result.ToString() );this.Progressbar.Value = 0;}}#endregion
Звітування прогресу виконання фонової операції
Ви можете звітувати про хід виконання фонової операції на основний потік шляхом виклику методу ReportProgress. Цей метод викликає подію ProgressChanged і дозволяє передавати параметр, що вказує відсоток прогресу, який був завершений. Перед тим необхідно встановити пропертю WorkerReportsProgess класу BackgroundWorker в true.
public MainWindow(){InitializeComponent();backgroundworker.WorkerSupportsCancellation = true;backgroundworker.WorkerReportsProgress = true;backgroundworker.DoWork += backgroundworker_DoWork;backgroundworker.RunWorkerCompleted += backgroundworker_RunWorkerCompleted;backgroundworker.ProgressChanged += backgroundworker_ProgressChanged;}
void backgroundworker_DoWork(object sender, DoWorkEventArgs e){if (e.Argument != null && e.Argument is System.Int32){int number = (int)e.Argument;if (number == 1){e.Result = 1;backgroundworker.ReportProgress(100);return;}int factorial = 1;for (int i = 2; i < number+1; i++){if (backgroundworker.CancellationPending){e.Cancel = true;return;}Thread.Sleep(500);factorial = factorial * i;backgroundworker.ReportProgress(i*100 / number);}e.Result = factorial;}}
#region Reporting the Progress of a Background Processvoid backgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e){this.Progressbar.Value = e.ProgressPercentage;}#endregion
Скачати приклад
Комментариев нет:
Отправить комментарий