C#. Windows Forms. Елемент управління (компонент) BackgroundWorker




Елемент управління (компонент) BackgroundWorker. Робота з потоками (фоновими операціями). Огляд методів, властивостей, подій


Зміст


Пошук на інших ресурсах:

1. Елемент управління BackgroundWorker. Призначення

Елемент управління (компонент, клас) BackgroundWorker реалізує виконання окремого потоку в додатках типу Windows Forms. Щоб використати можливості BackgroundWorker потрібно розмістити його на формі (рисунок 1).

C#. Windows Forms. Розміщення компонента BackgroundWorker на панелі ToolBox та на формі

Рисунок 1. Розміщення компонента BackgroundWorker на панелі ToolBox та на формі

Після розміщення, система створить відповідний екземпляр типу BackgroundWorker та дасть йому ім’я за замовчуванням. На рисунку 1 створюється екземпляр (об’єкт) з іменем backgroundWorker1. Для створеного екземпляру система пропонує ряд властивостей та подій, які описуються далі.

 

2. Властивості BackgroundWorker

При активації екземпляру типу BackgroundWorker відображається перелік властивостей цього елементу управління (рисунок 2).

C#. Windows Forms. Властивості елементу управління BackgroundWorker

Рисунок 2. Перелік властивостей елементу управління BackgroundWorker

 

2.1. Властивість Name. Задати ім’я екземпляру класу

Властивість Name задає ім’я екземпляру класу BackgroundWorker. Система автоматично генерує імена за замовчуванням. Перший екземпляр у програмі має ім’я backgroundWorker1, другий екземпляр backgroundWorker2 і т.д. За бажанням можна змінити ім’я екземпляру BackgroundWorker.

C#. Windows Forms. Компонент BackgroundWorker. Властивість Name

Рисунок 3. Компонент BackgroundWorker. Властивість Name = backgroundWorker1

 

2.2. Властивість GenerateMember. Наявність/відсутність екземпляру класу

Властивість GenerateMember задає наявність/відсутність екземпляру класу BackgroundWorker.

Якщо GenerateMember = true (за замовчуванням), то система згенурує екземпляр з іменем, заданим у полі Name (за замовчуванням backgroundWorker1) у файлі Form1.Designer.cs

partial class Form1
{
  ...

  private System.ComponentModel.BackgroundWorker backgroundWorker1;

}

тут

  • Form1 – ім’я екземпляру головної форми програми;
  • backgroundWorker1 – ім’я екземпляру потоку.

Якщо GenerateMember = false, то екземпляр не створюється. Якщо у процесі роботи програми потрібно звертатись до екземпляру класу BackgroundWorker, то обов’язково потрібно встановити цю властивість у значення true.

C#. Windows Forms. Компонент BackgroundWorker. Властивість GenerateMember

Рисунок 4. Властивість GenerateMember. Генерування екземпляру, якщо GenerateMember = true

 

2.3. Властивість Modifiers. Видимість з інших форм чи класів

Властивість Modifiers призначена для встановлення видимості екземпляру типу BackgroundWorker (рисунок 5). Властивість може приймати одне з наступних значень:

  • private;
  • protected;
  • public;
  • internal;
  • protected internal.

Більш детально про використання модифікаторів доступу до членів класу можна прочитати тут.

 

C#. Windows Forms. Компонент BackgroundWorker. Властивість Modifiers

Рисунок 5. Властивість Modifiers

Якщо для екземпляру типу BackgroundWorker у вікні властивостей встановити, наприклад, значення

Modifiers = public

то частина класу форми Form1, яка розміщується у файлі Form1.Designer.cs буде містити public-оголошення екземпляру типу BackgroundWorker

...

partial class Form1
{

  ...

  public System.ComponentModel.BackgroundWorker backgroundWorker1;
}

...

Це означатиме, що екземпляр backgroundWorker1 буде видимий з інших модулів, просторів імен, класів тощо.

 

2.4. Властивість WorkerReportsProgress. Задати можливість корегування процесу виконання

Властивість WorkerReportsProgress визначає, чи потрібно у програмі відображати хід виконання потоку (прогрес виконання). На рисунку 5 зображено налаштування властивості у значення False.

C#. Windows Forms. Компонент BackgroundWorker. Властивість WorkerReportsProgress

Рисунок 6. Властивість WorkerReportsProgress

Програмний код оголошення властивості у класі BackgroundWorker має вигляд

public bool WorkerReportsProgress { get; set; }

Якщо WorkerReportsProgress = true, то можна відобразити звіт про виконання потоку (прогрес) шляхом виклику методу ProgressChanged(). У противному випадку, відобразити прогрес виконання потоку не вдасться і виклик методу ProgressChanged() призведе до помилки.

Більш детально про те, як реалізувати прогрес виконання потоку, можна переглянути тут.

 

2.5. Властивість WorkerSupportsCancellation. Задати можливість відміни виконання потоку

Властивість WorkerSupportsCancellation дозволяє задавати можливість відміни виконання потоку. На рисунку 7 відображено спосіб налаштування властивості в режимі проектування.

 

C#. Windows Form. Елемент управління BackgroundWorker. Властивість WorkerSupportsCancellation

Рисунок 7. Властивість WorkerSupportsCancellation

Згідно документації, оголошення властивості має вигляд:

public bool WorkerSupportsCancellation { get; set; }

Якщо значення властивості true, то потік підтримує асинхронну відміну виконання.

Для екземпляру потоку backgroundWorker1 у програмі цю властивість можна змінювати так

...

// Програмне задавання властивості
backgroundWorker1.WorkerSupportsCancellation = true;

...

 

2.6. Властивість CancellationPending. Визначення факту відміни виконання потоку

Властивість CancellationPending призначена для визначення того, чи була дана команда відміни виконання фонової операції (потоку). Оголошення властивості має вигляд:

public bool CancellationPending { get; }

За замовчуванням значення властивості рівне false. Перевірку значення властивості CancellationPending потрібно вписувати в обробник події DoWork.

Приклад.

// Виконання потоку, обробник події DoWork
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{

  ...

  // Цикл виконання потоку
  for (int i=0; i<1000; i++)
  {
    ...

    // Перевірка, чи була виконана команда відміни виконання потоку
    if (backgroundWorker1.CancellationPending)
      break;
  }
}

 

2.7. Властивість isBusy. Перевірка, чи виконується на даний момент потік

Властивість isBusy повертає значення, яке визначає, чи виконує екземпляр типу BackgroundWorker асинхронну операцію. Іншими словами, isBusy визначає, чи виконується на даний момент потік, що зв’язаний з екземпляром типу BackgroundWorker. Оголошення властивості наступне

public bool IsBusy { get; }

Властивість isBusy не відображається у вікні Properties. Ця властивість використовується безпосередньо у програмі.
Якщо потік, якому відповідає екземпляр backgroundWorker1 виконується, то це означає, що був викликаний метод

backgroundWorker1.RunWorkerAsync();

Якщо спробувати ще раз викликати цей метод для даного екземпляру, то буде згенерована виключна ситуація. Це пояснюється тим, що потік backgroundWorker1 ще виконується і зайнятий. Саме тому, для перевірки зайнятості потоку використовується властивість isBusy.
З врахуванням вищесказаного, обробник події запуску потоку на виконання повинен мати такий вигляд

// Запустити потік
private void button1_Click(object sender, EventArgs e)
{
  // Запустити потік з перевіркою на зайнятість
  if (!backgroundWorker1.IsBusy)
    backgroundWorker1.RunWorkerAsync();
}

 

3. Методи класу BackgroundWorker
3.1. Метод ReportProgress(). Відобразити прогрес виконання потоку

Метод ReportProgress() викликає подію ProgressChanged, в якій можна задавати візуалізацію ходу виконання задачі (прогрес виконання). Згідно з документацією метод має дві перевантажені реалізації. Найбільш вживана з них наступна

public void ReportProgress(int percentProgress);

тут

  • percentProgress – цілочисельне значення від 0 до 100, яке визначає відсоток виконаної роботи.

Даний метод можна викликати тільки у випадку, якщо властивість WorkerReportsProgress встановлено в значення true (див. п. 3.4). Якщо WorkerReportsProgress встановлено в значення false, то при виклику методу буде згенероване виключення типу System.InvalidOperationException.

Приклад. Щоб вивести значення еквівалентне 55 відсоткам потрібно написати такий код

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  ...

  try
  {
    // вказати 55 відсотків виконаних робіт у потоці
    backgroundWorker1.ReportProgress(55);
  }
  catch (InvalidOperationException exception)
  {
    // Вивести повідомлення про помилку
    MessageBox.Show(exception.Message);
  }

  ...
}

 

3.2. Метод RunWorkerAsync(). Запуск фонової операції (потоку)

Метод RunWorkerAsync() призначений для запуску потоку на виконання. Оголошення методу

public void RunWorkerAsync();

Наприклад, для екземпляру з іменем backgroundWorker1 запуск фонової операції (потоку) буде таким

// Запустити потік
if (!backgroundWorker1.IsBusy)
  backgroundWorker1.RunWorkerAsync();

 

3.3. Метод CancelAsync(). Відмінити фонову операцію

Метод CancelAsync() дає запит на відміну фонової операції (потоку). Оголошення методу має вигляд

public void CancelAsync();

Щоб використовувати метод CancelAsync() потрібно, щоб властивість WorkerSupportsCancellation була рівна true. У противному випадку буде згенеровано виключення типу InvalidOperationException.

Приклад.

...

// Відмінити виконання потоку
try
{
  backgroundWorker1.CancelAsync();
}
catch(InvalidOperationException exception)
{
  // Вивести повідомлення про помилку
  MessageBox.Show(exception.Message);
}

...

 

4. Події

Клас BackgroundWorker містить такі основні події:

  • DoWork – виникає після запуску потоку методом RunAsync(). В обробник цієї події вписується код виконання потоку. Таким кодом може бути, наприклад, цикл сортування масиву, пошуку даних в масиві, тощо;
  • ProgressChanged – виникає, коли робочий потік вказує на те, що був досягнутий деякий прогрес. Щоб викликати подію ProgressChanged в обробнику події DoWork вказується зміна (досягнення) прогресу виконання з допомогою методу ReportProgress(). У свою чергу, виникнення події ProgressChanged призведе до виклику обробника цієї події. В обробнику події ProgressChanged вказується код візуалізації прогресу з допомогою поширених компонент, таких як ProgressBar, Label тощо.
  • RunWorkerCompleted – виникає, коли відбувається завершення потоку виконання. Завершення потоку може бути внаслідок виконаної роботи, виникнення помилки або відміни виконання потоку. В обробник цієї події доцільно вписувати код завершальних операцій, виведення відповідних повідомлень тощо.

Вікно з переліком подій елементу управління BackgroundWorker зображено на рисунку 8.

C#. Windows Forms. Події елементу управління BackgroundWorker

Рисунок 8. Події елементу управління BackgroundWorker

Більш детально про взаємодію між обробниками подій DoWork, ProgressChanged, RunWorkerCompleted можна прочитати в наступній темі.

 


Зв’язані теми