Чтение онлайн

ЖАНРЫ

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

Салмре Иво

Шрифт:

Рис. 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);

}

//Выйти из потока...

 }

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

 //Конечный автомат

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

 public void setProcessingState(ProcessingState nextState) {

//B любой момент времени только одному потоку выполнения

//могут быть разрешены попытки изменить состояние

lock(m_useForStateMachineLock) {

//B случае попытки повторного вхождения в текущее состояние

//никакие дополнительные действия не выполняются

if (m_processingState == nextState) {

return;

}

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

//Простейший защитный код, гарантирующий

//невозможность перехода в другое состояние, если задача

Поделиться с друзьями: