Листинг 5.4. Код программы нахождения простых чисел, предназначенный для выполнения фоновым потоком
using System;
public class FindNextPrimeNumber
{
//Определить возможные состояния
public enum ProcessingState {
notYetStarted,
waitingToStartAsync,
lookingForPrime,
foundPrime,
requestAbort,
aborted
}
int m_startTickCount;
int m_endTickCount;
long m_startPoint;
long m NextHighestPrime;
ProcessingState m_processingState;
//---------------------------
//Простейший конечный автомат
//---------------------------
public void setProcessingState(ProcessingState nextState) {
//-----------------------------------------------------
// Простейший защитный код, гарантирующий невозможность
// перехода в другое состояние в случае успешного
// завершения задачи или успешной отмены ее выполнения
//-----------------------------------------------------
if ((m_processingState == ProcessingState.aborted) || (m_processingState == ProcessingState.foundPrime)) {
return;
}
//Разрешить изменение состояния
lock(this) {
m_processingState = nextState;
}
}
public ProcessingState getProcessingState() {
ProcessingState currentState; //Безопасное выполнение потока
lock(this) {
currentState = m_processingState;
}
return currentState;
}
public int getTickCountDelta() {
if (getProcessingState() == ProcessingState.lookingForPrime) {
throw new Exception("Продолжается поиск простого числа! Окончательное время еще не вычислено");
}
return m_endTickCount - m_startTickCount;
}
//-------------------------
// Возвращает простое число
//-------------------------
public long getPrime() {
if (getProcessingState() != ProcessingState.foundPrime) {
throw new Exception("простое число еще не найдено!");
}
return m_NextHighestPrime;
}
//Конструктор класса
public FindNextPrimeNumber(long startPoint) {
setProcessingState(ProcessingState.notYetStarted);
m_startPoint = startPoint;
}
//------------------------------------------------------------
// Создает новый рабочий поток, который будет вызывать функцию
// "findNextHighestPrime()"
//------------------------------------------------------------
public void findNextHighestPrime_Async() {
System.Threading.ThreadStart threadStart;
threadStart = new System.Threading.ThreadStart(findNextHighestPrime);
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(threadStart);
//Состояние должно отвечать, что поиск продолжается
setProcessingState(ProcessingState.waitingToStartAsync);
newThread.Start();
//-----------------------------------------------------------------
// Основной рабочий поток. Этот поток запускает поиск очередного
// простого числа и выполняется до тех пор, пока не произойдет
// одно из следующих двух событий:
// (а) найдено очередное простое число
// (b) от внешнего (по отношению к данному) потока поступила команда
// прекратить выполнение
//------------------------------------------------------------------
public void findNextHighestPrime() {
//Если поступила команда прекратить выполнение, то поиск
//даже не должен начинаться
if (getProcessingState() == ProcessingState.requestAbort) {
goto finished_looking;
}
//Состояние должно отвечать, что поиск продолжается
setProcessingState(ProcessingState.lookingForPrime);
m_startTickCount = System.Environment.TickCount;
long currentItem;
//Проверить, является ли число нечетным
if ((m_startPoint & 1) == 1) {
//Число является нечетным, начать поиск со следующего нечетного числа