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. Свойство GenerateMember

Рисунок 4. Генерирование экземпляра, если GenerateMember = true

  

2.3. Свойство Modifiers. Видимость из других форм или классов

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

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

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

C#. Windows Forms. Свойство 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. Свойство WorkerReportsProgress

Рисунок 6. Свойство WorkerReportsProgress

Программный код объявления свойства в классе BackgroundWorker имеет вид

public bool WorkerReportsProgress { get; set; }

Если WorkerReportsProgress = true, то можно отобразить отчет о выполнении потока (прогресс) путем вызова метода ProgressChanged(). В противном случае, отобразить прогресс выполнения потока не удастся и вызов метода ProgressChanged() приведет к ошибке.

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

  

2.5. Свойство WorkerSupportsCancellation. Задать возможность отмены выполнения потока

Свойство WorkerSupportsCancellation позволяет задавать возможность отмены выполнения потока. На рисунке 7 отражен способ настройки свойства в режиме проектирования.

C#. Windows Forms. Свойство 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 можно прочитать в следующей теме.

  


Связанные темы