If (m_findNextPrimeNumber.getProcessingState = _
FindNextPrimeNumber.ProcessingState.aborted) Then
Timer1.Enabled = False
m_findNextPrimeNumber = Nothing
setCalculationStatusText("Поиск простого числа отменен")
Return
End If
'----------------------------------
'Удалось ли найти правильный ответ?
'----------------------------------
If (m_findNextPrimeNumber.getProcessingState = _
FindNextPrimeNumber.ProcessingState.foundPrime) Then
Timer1.Enabled = False
'Отобразить результат
setCalculationStatusText("Число найдено! Следующее простое число = " + _
m_findNextPrimeNumber.getPrime().ToString())
m_findNextPrimeNumber = Nothing
Return
End If
'--------------------------------------
'Вычисления продолжаются. Информировать
'пользователя о состоянии выполнения...
'--------------------------------------
'Получить два выходных значения
Dim numberCalculationsToFar As Long
Dim currentItem As Long
m_findNextPrimeNumber.getExecutionProgressInfo( _
numberCalculationsToFar, currentItem)
setCalculationStatusText("Вычисления продолжаются. Поиск в области: " + _
CStr(currentItem) + ". " + _
"Для вас выполнено " + CStr(numberCalculationsToFar) + _
" расчетов!")
End Sub
Листинг 9.5. Код класса FindNextPrimeNumber.cs
Option Strict On
Imports System
Public Class FindNextPrimeNumber
'Перечисляем возможные состояния
Public Enum ProcessingState
notYetStarted
waitingToStartAsync
lookingForPrime
foundPrime
requestAbort
aborted
End Enum
Private m_startPoint As Long
Private m_NextHighestPrime As Long
'Поиск какого количества элементов выполнен?
Private m_comparisonsSoFar As Long
'Для какого элемента сейчас выполняется поиск простого числа?
Private m_CurrentNumberBeingExamined As Long
'Вызывается для обновления информации о состоянии выполнения
Public Sub getExecutionProgressInfo( _
ByRef numberCalculationsSoFar As Long, _
ByRef currentItemBeingLookedAt As Long)
'ПРИМЕЧАНИЕ. Мы используем блокирование потока для уверенности в том,
'что эти значения не считываются во время выполнения операции
'их записи. Поскольку доступ к m_comparisonsSoFar
'и m_CurrentNumberBeingExamined могут осуществлять
'одновременно несколько потоков, любая выполняемая над ними
'операция записи/считывания должна синхронизироваться с "блокировкой",
'что будет гарантировать "атомарность" этих операций
SyncLock (Me)
numberCalculationsSoFar = m_comparisonsSoFar
currentItemBeingLookedAt = m_CurrentNumberBeingExamined
End SyncLock
End Sub
Private m_processingState As ProcessingState
'---------------------------
'Простейший конечный автомат
'---------------------------
Public Sub setProcessingState(ByVal nextState As _
ProcessingState)
'Простейший защитный код, гарантирующий
'невозможность перехода в другое состояние, если задача
'либо успешно завершена, либо успешно отменена
If ((m_processingState = ProcessingState.aborted) _
OrElse (m_processingState = ProcessingState.foundPrime)) Then
Return
End If
'Разрешить изменение состояния
m_processingState = nextState
End Sub
Public ReadOnly Property getProcessingState() As ProcessingState
Get
Return m_processingState
End Get
End Property
'------------------------
'Возвращает простое число
'------------------------
Public Function getPrime() As Long
If (m_processingState <> ProcessingState.foundPrime) Then
Throw New Exception("Простое число еще не найдено!")
End If
Return m_NextHighestPrime
End Function
'Конструктор класса
Public Sub New(ByVal startPoint As Long)
setProcessingState(ProcessingState.notYetStarted)
m_startPoint = startPoint
End Sub
'-----------------------------------------------------------
'Создает новый рабочий поток, который будет вызывать функцию
'findNextHighestPrime()
'-----------------------------------------------------------
Public Sub findNextHighestPrime_Async()
Dim threadStart As System.Threading.ThreadStart
threadStart = _
New System.Threading.ThreadStart(AddressOf _
findNextHighestPrime)
Dim newThread As System.Threading.Thread
newThread = New System.Threading.Thread(threadStart)
'Состояние должно отвечать, что поиск продолжается
setProcessingState(ProcessingState.waitingToStartAsync)
newThread.Start()
End Sub
'-------------------------------------------------------------
'Основной рабочий поток. Этот поток запускает поиск очередного
'простого числа и выполняется до тех пор, пока не произойдет
'одно из следующих двух событий:
' (а) найдено очередное простое число
' (b) от внешнего (по отношению к данному) потока поступила
Читать дальше