Cамоучитель по VB.NET

       

Многопоточность в простом приложении с графическим интерфейсом




Imports System.Text

Public Class RandomCharacters

Private m_Data As StringBuilder

Private m_CountDone As Boolean

Private mjength, m_count As Integer

Public Sub New(ByVal n As Integer)

m_Length = n -1

m_Data = New StringBuilder(m_length) MakeString()

End Sub

Private Sub MakeString()

Dim i As Integer

Dim myRnd As New Random()

For i = 0 To m_length



' Сгенерировать случайное число от 65 до 90,

' преобразовать его в прописную букву

' и присоединить к объекту StringBuilder

m_Data.Append(Chr(myRnd.Next(65.90)))

Next

End Sub

Public Sub StartCount()

GetEes()

End Sub

Private Sub GetEes()

Dim i As Integer

For i = 0 To m_length

If m_Data.Chars(i) = CChar("E") Then

m_count += 1

End If Next

m_CountDone = True

End Sub

Public Readonly

Property GetCount() As Integer Get

If Not (m_CountDone) Then

Throw New Exception("Count not yet done") Else

Return m_count

End If

End Get End Property

Public Readonly

Property IsDone()As Boolean Get

Return

m_CountDone

End Get

End Property

End Class

С двумя кнопками на форме связывается весьма простой код. В процедуре btn-Start_Click создается экземпляр приведенного выше класса RandomCharacters, инкапсулирующего строку с 10 миллионами символов:

Private Sub btnStart_Click(ByVal sender As System.Object.

ByVal e As System.EventArgs) Handles btnSTart.Click

Dim RC As New RandomCharacters(10000000)

RC.StartCount()

MsgBox("The number of es is " & RC.GetCount)

End Sub

Кнопка Cancel выводит окно сообщения:

Private Sub btnCancel_Click(ByVal sender As System.Object._

ByVal e As System.EventArgs)Handles btnCancel.Click

MsgBox("Count Interrupted!")

End Sub

При запуске программы и нажатии кнопки Start выясняется, что кнопка Cancel не реагирует на действия пользователя, поскольку непрерывный цикл не позволяет кнопке обработать полученное событие. В современных программах подобное недопустимо!

Возможны два решения. Первый вариант, хорошо знакомый по предыдущим версиям VB, обходится без многопоточности: в цикл включается вызов DoEvents. В .NET эта команда выглядит так:

Application.DoEvents()

В нашем примере это определенно нежелательно — кому захочется замедлять программу десятью миллионами вызовов DoEvents! Если вместо этого выделить цикл в отдельный поток, операционная система будет переключаться между потоками и кнопка Cancel сохранит работоспособность. Реализация с отдельным потоком приведена ниже. Чтобы наглядно показать, что кнопка Cancel работает, при ее нажатии мы просто завершаем программу.





Содержание раздела