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

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

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

Option Strict On
Imports System
Public Class FindNextPrimeNumber
'Определить возможные состояния
Public Enum ProcessingState
 notYetStarted
 waitingToStartAsync
 lookingForPrime
 foundPrime
 requestAbort
 aborted
End Enum
Private m_startTickCount As Integer
Private m_endTickCount As Integer
Private m_startPoint As Long
Private m_NextHighestPrime As Long
Private m_processingState As ProcessingState
'---------------------------
'Простейший конечный автомат
'---------------------------
Public Sub setProcessingState(ByVal nextState As ProcessingState)
 '------------------------------------------------------------
 'Простейший защитный код, гарантирующий
 'невозможность перехода в другое состояние в случае успешного
 'завершения задачи или успешной отмены ее выполнения
 '------------------------------------------------------------
 Dim currentState As ProcessingState
 currentState = getProcessingState()
 If ((currentState = ProcessingState.aborted) _
  OrElse (currentState = ProcessingState.foundPrime)) Then
  Return
 End If
 'Безопасное параллельное выполнение потоков
 SyncLock (Me)
  'Разрешить изменение состояния
  m_processingState = nextState
 End SyncLock
End Sub
Public Function getProcessingState() As ProcessingState
 Dim currentState As ProcessingState
 'Безопасное параллельное выполнение потоков
 SyncLock (Me)
  currentState = m_processingState
 End SyncLock
 Return currentState
End Function
Public Function getTickCountDelta() As Integer
 If (getProcessingState() = _
  ProcessingState.lookingForPrime) Then
  Throw New Exception( _
   "Продолжается поиск простого числа! Окончательное время еще не вычислено")
 End If
 Return m_endTickCount - m_startTickCount
End Function
'------------------------
'Возвращает простое число
'------------------------
Public Function getPrime() As Long
 If (getProcessingState() <> 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 threadStartAs 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) от внешнего (по отношению к данному) потока поступила команда
' прекратить выполнение
'------------------------------------------------------------------
Public Sub findNextHighestPrime()
 'Если поступила команда прекратить выполнение, то поиск даже
 'не должен начинаться
 If (getProcessingState() = ProcessingState.requestAbort) Then
  GoTo finished_looking
 End If
 'Состояние должно отвечать, что поиск продолжается
 setProcessingState(ProcessingState.lookingForPrime)
 m_startTickCount = System.Environment.TickCount
 Dim currentItemAs Long
 'Проверить, является ли число нечетным
 If ((m_startPointAnd 1) = 1) Then
  'Число является нечетным, начать поиск со следующего нечетного числа
  currentItem = m_startPoint + 2
 Else
  'Число является четным, начать поиск со следующего нечетного числа
  currentItem = m_startPoint + 1
 End If
 'Приступить к поиску простого числа
 While (getProcessingState() = ProcessingState.lookingForPrime)
  'В случае нахождения простого числа возвратить его
  If (isItemPrime(currentItem) = True) Then
   m_NextHighestPrime = currentItem
   'Обновить состояние
   setProcessingState(ProcessingState.foundPrime)
  End If
  currentItem = currentItem + 2
 End While
finished_looking:
 'Выход. К этому моменту либо от другого потока поступила
 'команда прекратить поиск, либо было найдено и записано
 'следующее наибольшее простое число
 'Зафиксировать время
 m_endTickCount = System.Environment.TickCount
 'Если поступил запрос прекратить выполнение,
 'сообщить, что выполнение процесса прекращено
 If (getProcessingState() = ProcessingState.requestAbort) Then
  setProcessingState(ProcessingState.aborted)
 End If
End Sub
'Вспомогательная функция, которая проверяет, является
'ли число простым
Private Function isItemPrime(ByVal potentialPrime As Long) As Boolean
 'Если число - четное, значит, оно не является простым
 If ((potentialPrime And 1) = 0) Then
  Return False
 End If
 'Продолжать поиск до тех пор, пока не будет превышено значение
 'квадратного корня из числа
 Dim end_point_of_searchAs Long end_point_of_search = _
  CLng(System.Math.Sqrt(potentialPrime) + 1)
 Dim current_test_itemAs Long = 3
 While (current_test_item <= end_point_of search)
  '---------------------------------------------------------
  'Проверить, не поступила ли команда прекратить выполнение!
  '---------------------------------------------------------
  If (getProcessingState() <> ProcessingState.lookingForPrime) Then
   Return False
  End If
  'Если число делится без остатка,
  'значит, оно не является простым
  If (potentialPrimeMod current_test_item = 0) Then
   Return False
  End If
  'Увеличить число на два
  current_test_item = current test_item + 2
 End While
 'Число является простым
 Return True
End Function
End Class

Оглавление книги


Генерация: 1.184. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз