Литмир - Электронная Библиотека
Содержание  
A
A

Пример использования фонового потока для выполнения отдельной задачи

Показанный в листинге 9.1 код представляет класс, который позволяет управлять выполнением задачи в фоновом потоке. Для отслеживания состояний подготовки приложения к выполнению, запуска нового потока, выполнения кода потоком и выхода из потока выполнения по завершении работы применяется конечный автомат.

Кроме того, в рассматриваемом примере основному потоку предоставляется возможность запрашивать прекращение выполнения фоновой задачи. Для уведомления потока, выполняющего фоновую задачу, о поступлении запроса на прекращение выполнения, используется вызов метода m_threadExecute.setProcessingState(ThreadExecuteTask.ProcessingState.requestAbort) из другого потока. За периодическую проверку этого состояния и осуществление возможного прекращения выполнения операции отвечает код, выполняемый фоновым потоком. Конечный автомат для класса ThreadExecuteTask представлен на рис. 9.1.

Программирование мобильных устройств на платформе .NET Compact Framework - image048.jpg

Рис. 9.1. Конечный автомат для отдельной задачи, выполняемой фоновым потоком

Листинг 9.1. Код для управления выполнением одиночной задачи фоновым потоком

using System;
 

public class ThreadExecuteTask {

 //Перечисляем возможные состояния

 public enum ProcessingState {

  //-------------------

  //Начальное состояние

  //-------------------

  //Пока ничего интересного не происходит

  notYetStarted,

  //-----------------

  //Рабочие состояния

  //-----------------

  //Ожидание запуска фонового потока

  waitingToStartAsync,

  //Выполнение кода в фоновом потоке

  running,

  //Запросить отмену выполнения вычислений

  requestAbort,

  //--------------------

  //Состояния завершения

  //--------------------

  //Состояние завершения: выполнение фонового потока

  //успешно завершено

  done,

  //Состояние завершения: выполнение потока отменено

  //до его завершения

  aborted

 }

 ProcessingState m_processingState;

 public delegate void ExecuteMeOnAnotherThread(ThreadExecuteTask checkForAborts);

 private ExecuteMeOnAnotherThread m_CallFunction;

 private object m_useForStateMachineLock;

 public ThreadExecuteTask(ExecuteMeOnAnotherThread functionToCall) {

  //Создать объект, который мы можем использовать

  //в конечном автомате в целях блокировки

  m_useForStateMachineLock = new Object();

  //Обозначить готовность к началу выполнения

  m_processingState = ProcessingState.notYetStarted;

  //Сохранить функцию, которую необходимо вызвать

  //в новом потоке

  m_CallFunction = functionToCall;

  //----------------------------------------------------------

  //Создать новый поток и вызвать в нем функцию на выполнение:

  // this.ThreadStartPoint()

  //----------------------------------------------------------

  System.Threading.ThreadStart threadStart;

  threadStart = new System.Threading.ThreadStart(ThreadStartPoint);

  System.Threading.Thread newThread;

  newThread = new System.Threading.Thread(threadStart);

  //Обозначить готовность к началу выполнения (в целях определенности

  //это важно сделать еще до того, как будет запущен поток!)

  setProcessingState(ProcessingState.waitingToStartAsync);

  //Дать ОС команду начать выполнение нового потока в асинхронном режиме

  newThread.Start();

  //Возвратить управление функции, вызывающей этот поток

 }

 //---------------------------------------------

 //Эта функция является точкой входа, вызываемой

 //для выполнения в новом потоке

 //---------------------------------------------

 private void ThreadStartPoint() {

  //Установить состояние обработки, соответствующее

  //выполнению функции в новом потоке!

  setProcessingState(ProcessingState.running);

  //Запустить на выполнение пользовательский код и передать указатель в

  //наш класс, чтобы этот код мог периодически проверять, не поступил ли

  //запрос на прекращение выполнения

  m_CallFunction(this);

  //Если выполнение не было отменено, изменить состояние таким образом,

  //чтобы оно соответствовало успешному завершению

  if (m_processingState != ProcessingState.aborted) {

   //Обозначить завершение выполнения

   setProcessingState(ProcessingState.done);

83
{"b":"947732","o":1}