Как и со многими другими классами .NET, работать с работником — одно удовольствие. Надо лишь сказать, что ему делать после того, как он получит команду: "Приступай", и как вести себя по окончании работы. Первое действие представляет собой подписку на событие DoWork (создание делегата). Это выглядит так.
ordersWorker.DoWork += new DoWorkEventHandler (ordersWorker_DoWork);
Само событие DoWork будет сгенерировано лишь после того, как работник получит команду приступить к работе. Такой командой является вызов метода RunWorkerAsync. Это выглядит так.
ordersWorker.RunWorkerAsync ((string) row["CustomerID"]);
Смотрите, здесь неясно, что делать, но ясно, что получить в качестве входного параметра. Далее в работу включается операционная система. Она генерирует событие DoWork, вызывает задание делегата, в котором мы вызываем метод GetOrders. Это выглядит так.
void ordersWorker_DoWork (object sender, DoWorkEventArgs e)
{
e.Result = GetOrders (e.Argument.ToString ());
}
Здесь уже ясно, что делать и куда поместить результат. В этот момент система запускает другой поток, который выполняет (асинхронно) наш метод GetOrders. Заметьте, что идентификатор клиента (CustomerID), необходимый для выполнения задания, сгенерирован и передан нам системой (вместе с событием DoWork). Он спрятан в рамках объекта DoWorkEventArgs и выглядит, как e.Argument.
По завершении метода GetOrders генерируется событие RunWorkerCompleted. Мы должны ввести в класс формы функцию его обработки, в теле которой можно получить результат, опять же из параметра, генерируемого системой.
void ordersWorker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
{
ordersSource.DataSource = e.Result;
}
Синхронизатор позиции таблицы заказов ordersSource получает желаемое подмножество строк (отфильтрованный DataView) и это заставляет DataGridView, которым управляет ordersSource, отобразить искомые заказы. Итак, основная логика управления работником ясна, но к ней следует добавить логику управления элементом progressBar и курсором ожидания. С помощью этих элементов имитируется ситуация длительного ожидания при обращении к Web-сервису. Все вместе выглядит так.
¨ Оставьте без изменений метод ordersWorker_DoWork.
¨ В реакцию на загрузку формы добавьте вызов метода, создающего BackgroundWorker.
private void MainForm_Load (object sender, EventArgs e)
{
SetBinding();
FillDictionary();
SetBackgroundWorker();
customersSource.Position = 0;
customersSource_CurrentChanged (customersSource, EventArgs.Empty);
}
¨ Полностью замените метод, обрабатывающий событие CurrentChanged, которое генерирует синхронизатор.
void customersSource_CurrentChanged (object sender, EventArgs e)
{
DataRowView row = customersSource.Current as DataRowView;
if (row != null) // Синхронизация картинки с флагом
{
string country = (string)row["Country"];
if (flags.ContainsKey(country))
pic.Image = flags[country];
ordersSource.DataSource = null; // Сотрем старые заказы
UseWaitCursor = true;
ShowProgress (true);
ordersWorker.RunWorkerAsync ((string) row["CustomerID"]); // Генерируем событие DoWork
}
}
¨ Введите в состав класса формы метод, создающий и настраивающий объект класса BackgroundWorker.
private void SetBackgroundWorker () // Единократное создание работника
{
ordersWorker = new BackgroundWorker ();
ordersWorker.DoWork += new DoWorkEventHandler (ordersWorker_DoWork);
ordersWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler (ordersWorker_RunWorkerCompleted);
timer = new System.Windows.Forms.Timer ();
timer.Interval = 100;
timer.Tick += new EventHandler (timer_Tick);
}
¨ Введите метод, управляющий таймером и индикатором прогресса.
private void ShowProgress (bool start)
{
if (start)
timer.Start();
else
timer.Stop();
progressBar.Visible = start;
progressBar.Value = 0;
}
¨ Введите метод, реагирующий на событие истечения кванта времени таймера. Здесь мы продвигаем вперед индикатор прогресса (изменяем его позицию — свойство Value).
void timer_Tick (object sender, EventArgs e) { progressBar.PerformStep(); }
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.