Иво Салмре - Программирование мобильных устройств на платформе .NET Compact Framework
'не должен начинаться
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
Листинг 5.5. Тестовая программа, которая вызывает на выполнение приведенный выше код фонового потока, осуществляющего поиск простого числа'----------------------------------------------------------
'Код, обрабатывающий событие щелчка на кнопке Button1 формы
'Вызвать из этого потока функцию поиска простого числа!
'(Это приведет к блокированию потока)
'----------------------------------------------------------
Private Sub Button1_Click(ByVal senderAs System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim testItem As Long
testItem = System.Convert.ToInt64("123456789012345")
Dim nextPrimeFinder As FindNextPrimeNumber
nextPrimeFinder = New FindNextPrimeNumber(testItem)
nextPrimeFinder.findNextHighestPrime()
Dim nextHighestPrime As Long
nextHighestPrime = nextPrimeFinder.getPrime()
MsgBox(CStr(nextHighestPrime))
'Сколько времени заняли вычисления?
Dim calculation_time As Integer
calculationtime = nextPrimeFinder.getTickCountDelta()
MsgBox(CStr(calculation time) + " мс")
End Sub
'------------------------------------------------------------------------
'Код, обрабатывающий событие щелчка на кнопке Button2 формы
'Вызвать функцию поиска простого числа из другого потока!
'(Данный поток блокироваться не будет)
'Для отслеживания состояния выполнения задачи используем конечный автомат
'------------------------------------------------------------------------
Private Sub Button2_Click(ByVal senderAs System.Object, _
ByVal eAs System.EventArgs) Handles Button2.Click
Dim testItem As Long
testItem = System.Convert.ToInt64("123456789012345")
Dim nextPrimeFinderAs FindNextPrimeNumber
nextPrimeFinder = New FindNextPrimeNumber(testItem)
'-----------------------------------
'Выполнить обработку в другом потоке
'-----------------------------------
nextPrimeFinder.findNextHighestPrime_Async()
'Войти в цикл и ожидать до тех пор, пока не будет найдено простое число
'или выполнение не будет прекращено
While ((nextPrimeFinder.getProcessingState() <> _
FindNextPrimeNumber.ProcessingState.foundPrime) And _
(nextPrimeFinder.getProcessingState() <> _
FindNextPrimeNumber.ProcessingState.aborted))
'ТОЛЬКО В ТЕСТОВОМ КОДЕ:
'Отобразить окно сообщений и предоставить пользователю возможность
'убрать его с экрана.
'Это позволяет организовать паузу
MsgBox("Поиск продолжается... Щелкните на кнопке OK")
'Мы могли бы прекратить поиск путем следующего вызова функции:
'nextPrimeFinder.setProcessingState(
' FindNextPrimeNumber.ProcessingState.requestAbort)
End While
'Осуществить корректный выход в случае прекращения поиска
If (nextPrimeFinder.getProcessingState() = _
FindNextPrimeNumber.ProcessingState.aborted) Then
MsgBox("Поиск прекращен!")
Return
End If
Dim nextHighestPrime As Long
nextHighestPrime = nextPrimeFinder.getPrime()
MsgBox(CStr(nextHighestPrime))
'Сколько времени заняли вычисления?
Dim calculation_time As Integer
calculation_time = nextPrimeFinder.getTickCountDelta()
MsgBox(CStr(calculation_time) + " мс")
End Sub
Примеры к главе 7 (производительность: введение)
Листинг 7.1. Пример кода для измерения временных интервалов, который вы можете использовать для хронометрирования работы своих приложенийOption Strict On
Imports System
Friend Class PerformanceSampling
'Значение этого параметра может быть задано произвольным, но количество
'тестовых интервалов, равное 8, представляется достаточным для большинства
'случаев
Const NUMBER_SAMPLERS As Integer = 8
Private Shared m_perfSamplesNames(NUMBER_SAMPLERS) As String
Private Shared m_perfSamplesStartTicks(NUMBER_SAMPLERS) As Integer
Private Shared m_perfSamplesDuration(NUMBER_SAMPLERS) As Integer
'---------------------------------------------------------------------------
'Определить начальное значение счетчика тактов системных часов для интервала
'---------------------------------------------------------------------------
Friend Shared Sub StartSample(ByVal sampleIndex As Integer, _
ByVal sampleName As String)
m_perfSamplesNames(sampleIndex) = sampleName
m_perfSamplesStartTicks(sampleIndex) = System.Environment.TickCount()
End Sub
'--------------------------------------------------------------------------
'Определить конечное значение счетчика тактов системных часов для интервала
'--------------------------------------------------------------------------
Friend Shared Sub StopSample(ByVal sampleIndex As Integer)
Dim stopTickCountAs Integer = System.Environment.TickCount
'Счетчик тактов системных часов сбрасывается в ноль каждые 24,9 дня
'(что соответствует примерно 2 миллиардам мс)
'Эта маловероятная возможность будет принята нами во внимание
If (stopTickCount >= m_perfSamplesStartTicks(sampleIndex)) Then
'Обычно будет выполняться этот код
m_perfSamplesDuration(sampleIndex) = _
stopTickCount - m_perfSamplesStartTicks(sampleIndex)
Else
'Значение счетчика тактов "завернулось" через ноль, и мы
'должны это учесть
m_perfSamplesDuration(sampleIndex) = stopTickCount + _
(Integer.MaxValue - m_perfSamplesStartTicks(sampleIndex)) + 1
End If
End Sub
'-------------------------------------------
'Возвратить длительность тестового интервала
'(в миллисекундах)
'-------------------------------------------
Friend Shared Function GetSampleDuration(ByVal sampleIndex _
As Integer) As Integer
Return m_perfSamplesDuration(sampleIndex)
End Function
'Возвращает длительность истекшего тестового
' интервала в секундах
Friend Shared Function GetSampleDurationText(ByVal _
sampleIndexAs Integer) As String
Return m_perfSamplesNames(sampleIndex) + ": " + _
System.Convert.ToString( _
(m_perfSamplesDuration(sampleIndex) / CDbl(1000.0)) ) + " секунд."