Выбрать главу

'Код, обрабатывающий событие щелчка на кнопке 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)) ) + " секунд."

End Function

End Class

Листинг 7.2. Тестовая программа, демонстрирующая использование приведенного выше кода для измерения временных интервалов

Private Sub Button1_Click(ByVal senderAs System.Object, _

 ByVal e As System.EventArgs) Handles Button1.Click

 Const TEST_SAMPE_INDEXAs Integer = 2 'Выбрать любой допустимый индекс

 'Начать измерение

 PerformanceSampling.StartSample(TEST_SAMPE_INDEX, "TestSample")

 'Отобразить окно сообщений

 MsgBox("Для прекращения измерения нажмите кнопку OK")

 'Прекратить измерение