Елемент управління BackgroundWorker. Відображення прогресу виконаних робіт. Відміна виконання потоку
Дана тема є продовженням теми:
Зміст
- 1. Схема візуалізації прогресу виконаної роботи в потоці
- 2. Алгоритм візуалізації прогресу виконаних робіт у потоці
- 3. Відміна виконання потоку. Схема взаємодії між обробниками подій
- 4. Послідовність дій (алгоритм) відміни виконання потоку
- Зв’язані теми
Пошук на інших ресурсах:
1. Схема візуалізації прогресу виконаної роботи в потоці
На рисунку 1 зображено схему за якою відбувається взаємодія між обробниками подій для відображення прогресу в потоці (фоновій операції). На основі даної схеми описується алгоритм прогресу виконаних робіт (дивіться п.2).
Рисунок 1. Візуалізація прогресу виконаних робіт
⇑
2. Алгоритм візуалізації прогресу виконаних робіт у потоці
Щоб відобразити прогрес виконаної роботи (хід виконання) в потоці, потрібно використати наступні елементи класу BackgroundWorker:
- властивість WorkerReportProgress;
- метод ReportProgress().
Послідовність дій, що реалізують відображення прогресу виконання потоку наступна.
1. В режимі проектування задати властивість WorkerReportProgress = true.
2. В обробнику події DoWork викликати метод ReportProgress, в якому вказати відсоток виконаної роботи.
Наприклад, якщо в потоці виконується звичайний цикл від 1 до 100, то задавання відсотку буде приблизно таким:
// Обробник події DoWork private void backgroundWorker1_DoWork(...) { // ... for (i = 1; i<=100; i++) { // Дії, які виконуються в циклі // ... // Викликати обробник події ProgressChanged try { backgroundWorker1.ReportProgress((i*100)/100); } catch(InvalidOperationException exception) { MessageBox.Show(exception.Message); } } }
тут backgroundWorker1 – назва екземпляру потоку виконання для якого потрібно реалізувати відображення ходу виконання задачі.
3. В обробнику події ProgressChanged відобразити значення відсотку в деякому візуальному компоненті. Саме значення відсотку отримується з екземпляру e класу даних ProgressChangeEventArgs.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Відобразити відсоток у label1.Text label1.Text = Convert.ToString(e.ProgressPercentage) + "%"; // Відобразити зміну відсотку у progressBar1.Value progressBar2.Value = e.ProgressPercentage; }
тут
- label1 – елемент управління, що виводить значення відсотку (наприклад 28%);
- ProgressChangeEventArgs – клас, що представляє дані для події ProgressChanged;
- e.ProgressPercentage – властивість, яка повертає цілочисельний відсоток, що був сформований у п. 2 алгоритму при виклику методу ReportProgress().
⇑
3. Відміна виконання потоку. Схема взаємодії між обробниками подій
При виконанні деякого потоку (фонової операції), користувач має змогу відмінити виконання цього потоку. Клас BackgroundWorker має всі необхідні засоби для контролю за відміною виконання потоку. На рисунку 2 зображено схему взаємодії між обробниками подій, що задіяні у відміні виконання потоку.
Рисунок 2. Відміна виконання потоку. Взаємодія між обробниками подій
⇑
4. Послідовність дій (алгоритм) відміни виконання потоку
Тут описується загальний алгоритм дій, які потрібно виконати щоб коректно опрацювати відміну виконання потоку (фонової операції). Щоб відмінити потік використовуються наступні взаємозв’язані члени класу BackgroundWorker:
- властивість WorkerSupportsCancellation;
- метод CancelAsync();
- властивість CancellationPending.
Алгоритм, що реалізує коректну відміну виконання потоку, наступний.
1. Встановити властивість WorkerSupportsCancellation = true. Це дасть змогу використовувати засоби зупинки (відміни виконання) потоку.
2. В обробнику події кліку на кнопці зупинки потоку викликати метод CancelAsync()
// Відмінити виконання потоку private void button2_Click(object sender, EventArgs e) { try { backgroundWorker1.CancelAsync(); } catch(InvalidOperationException exception) { // Вивести повідомлення про помилку MessageBox.Show(exception.Message); } }
Тепер при кліку на кнопці зупинки потоку буде генеруватись відповідний запит в обробник події DoWork.
3. В обробнику події DoWork реалізувати перевірку на те, чи була викликана команда зупинки потоку. Це здійснюється шляхом перевірки властивості CancellationPending.
У найпростішому випадку для звичайного циклу код зупинки потоку матиме такий вигляд:
... private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ... // Цикл виконання потоку for (int i=0; i<1000; i++) { ... // Перевірка, чи була виконана команда відміни виконання потоку if (backgroundWorker1.CancellationPending) break; // якщо був запит на зупинку потоку, то вихід з циклу } } ...
4. В обробнику події RunWorkerCompleted виконати відповідні дії після завершення виконання потоку.
Для того, щоб розпізнати спосіб завершення потоку можна ввести додаткову внутрішню змінну, яка буде приймати відповідне значення.
У нижченаведеному коді в клас форми введено внутрішню змінну fCancelled. Ця змінна визначає, чи був відмінений потік користувачем і формується в обробнику події DoWork. Текст обробника події змінюється.
Результат завершення виконання потоку (нормальне завершення чи скасоване користувачем) виводиться в обробнику події RunWorkerCompleted. Також в цьому обробнику змінна fCancelled встановлюється в початковий стан.
// Клас форми public partial class Form1 : Form { // Визначає, як був завершений потік bool fCancelled = false; // якщо fCancelled=false, то виконання потоку було скасовано користувачем ... // Виконання потоку - обробник події DoWork - встановлює значення fCancelled private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ... // Цикл виконання потоку for (int i=0; i<1000; i++) { ... // Перевірка, чи була виконана команда відміни виконання потоку if (backgroundWorker1.CancellationPending) { // вказати, що виконання потоку було скасоване користувачем fCancelled = true; // завершити потік, вийти з циклу break; } } } // Обробник події завершення потоку private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Перевірка того, як був завершений потік if (fCancelled) label1.Text = "The thread was cancelled"; else label1.Text = "The thread was completed normally"; // Повернути fCancelled в початкове значення fCancelled = false; } ... }
⇑
Зв’язані теми
- Елемент управління BackgroundWorker. Робота з потоками (фоновими операціями). Огляд методів, властивостей, подій
- Розробка програми демонстрації роботи з потоками виконання. Елемент управління BackgroundWorker. Сортування в потоках алгоритмами вставки, бульбашки, вибором
⇑