Независимо от того, используется ли в программе просмотра изображений Windows XP фоновый поток для решения этой задачи или не используется (мне это неизвестно), она демонстрирует пример разумного применения асинхронной обработки для оптимизации рабочего процесса в случае наиболее распространенных действий. Прекрасная работа!
Пример использования фонового потока для выполнения отдельной задачи
Показанный в листинге 9.1 код представляет класс, который позволяет управлять выполнением задачи в фоновом потоке. Для отслеживания состояний подготовки приложения к выполнению, запуска нового потока, выполнения кода потоком и выхода из потока выполнения по завершении работы применяется конечный автомат.
Кроме того, в рассматриваемом примере основному потоку предоставляется возможность запрашивать прекращение выполнения фоновой задачи. Для уведомления потока, выполняющего фоновую задачу, о поступлении запроса на прекращение выполнения, используется вызов метода m_threadExecute.setProcessingState(ThreadExecuteTask.ProcessingState.requestAbort) из другого потока. За периодическую проверку этого состояния и осуществление возможного прекращения выполнения операции отвечает код, выполняемый фоновым потоком. Конечный автомат для класса ThreadExecuteTask представлен на рис. 9.1.
Рис. 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);
//Если выполнение не было отменено, изменить состояние таким образом,
//чтобы оно соответствовало успешному завершению
Читать дальше