412 000 произведений, 108 200 авторов.

Электронная библиотека книг » Иво Салмре » Программирование мобильных устройств на платформе .NET Compact Framework » Текст книги (страница 68)
Программирование мобильных устройств на платформе .NET Compact Framework
  • Текст добавлен: 18 июля 2025, 02:31

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


Автор книги: Иво Салмре



сообщить о нарушении

Текущая страница: 68 (всего у книги 69 страниц)

  VocabularyWord.WordGender.Feminine, _

  VocabularyWord.WordFunction.Noun)

 InsertEnglishGermanWordPair(cmd, "Clock", "Uhr", _

  VocabularyWord.WordGender.Feminine, _

  VocabularyWord.WordFunction.Noun)

 InsertEnglishGermanWordPair(cmd, "Cat", "Katze", _

  VocabularyWord.WordGender.Feminine, _

  VocabularyWord.KordFunction.Noun)

 'Имена существительные среднего рода

 InsertEnglishGermanWordPair(cmd, "Car", "Auto", _

  VocabularyWord.WordGender.Neuter, _

  VocabularyWord.WordFunction.Noun)

 InsertEnglishGermanWordPair(cmd, "Book", "Buch", _

  VocabularyWord.WordGender.Neuter, _

  VocabularyWord.WordFunction.Noun)

End Sub

'–

'Помещает слово в базу данных

'–

Private Shared Sub InsertEnglishGermanWordPair( _

 ByVal cmd As System.Data.SqlServerCe.SqlCeCommand, _

 ByVal englishWord As String, ByVal germanWord As String, _

 ByVal germanWordGender As VocabularyWord.WordGender, _

 ByVal wordFunction As VocabularyWord.WordFunction)

 cmd.CommandText = "INSERT INTO " + TRANSLATIONTABLE NAME + _

  "(" + TRANSLATIONTABLE_ENGLISH_COLUMN + ", " + _

  TRANSLATIONTABLE_GERMAN_COLUMN + ", " + _

  TRANSLATIONTABLE_GERMANGENDER_COLUMN + ", " + _

  TRANSLATIONTABLE_WORDFUNCTION_COLUMN + _

  ") VALUES ('" _

  + englishWord + "', '" + germanWord + "', '" _

  + System.Convert.ToString(CType(germanWordGender, Integer)) + "', '"

  + System.Convert.ToString(CType(wordFunction, Integer)) + "')"

 cmd.ExecuteNonQuery()

End Sub

End Class

Листинг 14.7. Пример кода управления данными для GameData.cs

Option Strict On

'–

'Код управления данными в памяти

'

'Этот код предназначен для управления представлением кода в памяти

'–

Imports System

Friend Class GameData

'Массив списков для сохранения загружаемых данных

Private Shared m_vocabularyWords_All As _

 System.Collections.ArrayList

Private Shared m_vocabularyWords_Nouns As _

 System.Collections.ArrayList

Private Shared m_vocabularyWords Verbs As _

 System.Collections.ArrayList

Private Shared m_vocabularyWords_Adjectives As _

 System.Collections.ArrayList

Private Shared m_vocabularyWords Adverbs As _

 System.Collections.ArrayList

Private Shared m_vocabularyWords_Prepositions As _

 System.Collections.ArrayList

Public Shared ReadOnly Property _

 isGameDataInitialized() As Boolean

 Get

  'Инициализация данных игры, если слова загружены

  Return Not (m_vocabularyWords_All Is Nothing)

 End Get

End Property

'Возвращает коллекцию всех имеющихся слов

Public Shared ReadOnly Property _

 AllWords() As System.Collections.ArrayList

 Get

  'Загрузить данные, если они не были инициализированы

  If (m_vocabularyWords_All Is Nothing) Then

   InitializeGameVocabulary()

  End If

  Return m_vocabularyWords_All

 End Get

End property

'Возвращает коллекцию всех имеющихся имен существительных

Public Shared ReadOnly Property _

 Nouns() As System.Collections.ArrayList

 Get

  'Загрузить данные, если они не были инициализированы

  If (m_vocabularyWords_Nouns Is Nothing) Then

   InitializeGameVocabulary()

  End If

  Return m_vocabularyWords_Nouns

 End Get

End Property

'==========================================================

'Загружает данные из нашей базы данных

'==========================================================

Public Shared Sub InitializeGameVocabulary()

 'Создать новый массив списков для хранения наших слов

 m_vocabularyWords_All = New System.Collections.ArrayList

 m_vocabularyWords_Nouns = New System.Collections.ArrayList

 m_vocabularyWords_Verbs = New System.Collections.ArrayList

 m_vocabularyWords_Adjectives = _

  New System.Collections.ArrayList

 m_vocabularyWords Adverbs = _

  New System.Collections.ArrayList

 m_vocabularyWords_Prepositions = _

  New System.Collections.ArrayList

 Dim dataReader As System.Data.IDataReader

 dataReader = DatabaseAccess.GetListOfWords()

 Dim newWord As VocabularyWord

 'Обойти все записи

 While (dataReader.Read())

  Dim thisword_gender As VocabularyWord.WordGender

  Dim thisword_function As VocabularyWord.WordFunction

  thisword_gender = CType(dataReader.GetInt32( _

   DatabaseAccess.DS_WORDS_COLUMNINDEX_GERMANGENDER), _

   VocabularyWord.WordGender)

  thisword_function = CType(dataReader.GetInt32( _

   DatabaseAccess.DS_WORDS_COLUMNINDEX_WORDFUNCTION), _

   VocabularyWord.WordFunction)

  'Поместить данные для только что считанного слова в класс

  newWord = New VocabularyWord(dataReader.GetString( _

   DatabaseAccess.DS_WORDS_COLUMNINDEX_ENGLISHWORD), dataReader.GetString( _

   DatabaseAccess.DS_WORDS_COLUMNINDEX_GERMANWORD), _

   thisword_gender, thisword_function)

  'Добавить новое слово в массив списков

  m_vocabularyWords_All.Add(newWord)

  'Слова могут принадлежать нескольким группам, поэтому

  'необходимо выполнить проверку с использованием операции логического И

  'для проверки того, что слово относится к данной категории

  If ((newWord.getWordFunction And _

   VocabularyWord.WordFunction.Noun) <> 0) Then

   m_vocabularyWords_Nouns.Add(newWord)

  End If

  If ((newWord.getWordFunction And _

   VocabularyWord.WordFunction.Verb) <> 0)

   Then m_vocabularyWords_Verbs.Add(newWord)

  End If

  If ((newWord.getWordFunction And _

   VocabularyWord.WordFunction.Adjective) <> 0) Then

   m_vocabularyWords_Adjectives.Add(newWord)

  End If

  If ((newWord.getWordFunction And _

   VocabularyWord.WordFunction.Adverb) <> 0) Then

   m_vocabularyWords_Adverbs.Add(newWord)

  End If

  If ((newWord.getWordFunction And _

   VocabularyWord.WordFunction.Preposition) <> 0) Then

   m_vocabularyWords_Prepositions.Add(newWord)

  End If

 End While

 'Закрыть объект DataReader

 dataReader.Close()

End Sub

End Class

Листинг 14.8. Пример кода управления данными для VocabularyWord.cs

Option Strict On

Imports System

'–

'Хранит данные слова из словаря

'–

Friend Class VocabularyWord

_

 Public Enum WordFunction

 Noun = 1

 Verb = 2

 Pronoun = 4

 Adverb = 8

 Adjective = 16

 Preposition = 32

 Phrase = 64

End Enum

Public Enum WordGender

 notApplicable = 0

 Masculine = 1

 Feminine = 2

 Neuter = 3

End Enum

Private m_englishWord As String

Private m_germanWord As String

Private m_germanGender As VocabularyWord.WordGender

Private m_wordFunction As VocabularyWord.WordFunction

Public ReadOnly Property EnglishWord() As String

 Get

  Return m_englishWord

 End Get

End Property

Public ReadOnly Property GermanWord() As String

 Get

  Return m_germanWord

 End Get

End Property

Public ReadOnly Property getWordFunction() As WordFunction

 Get

  Return m_wordFunction

 End Get

End Property

Public ReadOnly Property getWordGender() As WordGender

 Get

  Return m_germanGender

 End Get

End Property

'–

'Возвращает слово на немецком языке, которому предшествует артикль

'(например, 'der', 'die', 'das'), если он существует

'–

Public ReadOnly Property GermanWordWithArticleIfExists() As String

 Get

  If (m_germanGender = WordGender.notApplicable) Then

   Return Me.GermanWord

  End If

  Return Me.GenderArticle + " " + Me.GermanWord

 End Get

End Property

Public ReadOnly Property GenderArticle() As String

 Get

  Select Case (m_germanGender)

  Case WordGender.Masculine

   Return "der"

  Case WordGender.Feminine

   Return "die"

  Case WordGender.Neuter

   Return "das"

  End Select

  Return ""

 End Get

End Property

Public Sub New(ByVal enlgishWord As String, ByVal germanWord _

 As String, ByVal germanGender As WordGender, _

 ByVal wordFunction As WordFunction)

 m_englishWord = enlgishWord

 m_germanWord = germanWord

 m_germanGender = germanGender

 m_wordFunction = wordFunction

 End Sub

End Class

Примеры к главе 15 (передача данных)
Листинг 15.1. Простой код файлового ввода-вывода, иллюстрирующий различия между локальной и удаленной передачей данных

Этот код представляет собой всего лишь последовательность вызовов функций. Программистам на VB будет несложно написать его, используя в качестве образца код на C#.

Листинг 15.2. Имитация сбоев при передаче данных для тестирования приложения

'Флаги условной компиляции для нашего инструментированного кода

#Const DEBUG_SIMULATE_FAILURES = 1 'Имитировать сбои

'#Const DEBUG_SIMULATE_FAILURES = 0 'Не имитировать сбои

'–

'Глобальная переменная, которую мы хотим использовать для указания

'необходимости генерации исключений в процессе передачи данных

'–

#If DEBUG_SIMULATE_FAILURES <> 0 Then

'Переменная для хранения информация о следующем сбое

Shared g_failureCode As SimulatedFailures = _

 SimulatedFailures.noFailurePending

'Список сбоев, которые мы хотим имитировать

public enum SimulatedFailures

 noFailurePending 'No test failures pending

 'Имитируемые сбои:

 failInNextWriteSocketCode

 failInNextWebServiceCall

 failInNextFileIODuringFileOpen

 failInNextFileIODuringFileRead

 'и так далее

End Enum

#End If 'DEBUG_SIMULATE_FAILURES

'–

'Функция, которую мы используем для передачи данных.

'–

Private Sub writeDataToSocket( _

 ByVal mySocket As System.Net.Sockets.Socket, _

 ByVal dataToSend() As Byte)

 '–

 'Этот код следует компилировать лишь при тестировании сетевых сбоев

 '–

#If DEBUG_SIMULATE_FAILURES <> 0 Then

 'Если это сбой, который мы хотим тестировать, генерировать исключение

 If (g_failureCode = _

  SimulatedFailures.failInNextWriteSocketCode) Then

  'Сбросить этот сбой, чтобы он не возник

  'при следующем вызове этой функции

  g_failureCode = SimulatedFailures.noFailurePending

  Throw New Exception("Test communications failure: " + _

   g_failureCode.ToString())

 End If

#End If

 'Передать данные обычным образом.

 mySocket.Send(dataToSend)

End Sub

Листинг 15.3. Тестовый код, который необходимо поместить в класс формы для тестирования передачи и приема данных посредством механизма IrDA

'Имя, которое мы хотим присвоить сокету IrDA

Const myIrDASocketName As String = "IrDaTestFileTransmit"

Private Sub buttonTestFileSend_Click(ByVal sender As Object, _

 ByVal e As System.EventArgs) Handles buttonTestFileSend.Click

 'Создать простой текстовый файл, который мы хотим передать

 Const fileName As String = "myTestSendFile.txt"

 Dim textFileStream As System.IO.StreamWriter

 textFileStream = System.IO.File.CreateText(fileName)

 textFileStream.WriteLine("Today...")

 textFileStream.WriteLine("is а nice day")

 textFileStream.WriteLine("to go swim")

 textFileStream.WriteLine("in the lake")

 textFileStream.Close()

 Dim irdaFileSender As IrDAFileSend

 irdaFileSender = New IrDAFileSend(fileName, myIrDASocketName)

 'Имеется 2 режима: 1 – Sync (синхронный), 2 – Async (асинхронный)

 '1. Вызвать функцию в синхронном режиме

 'и блокировать поток выполнения до тех пор,

 'пока файл не будет передан

 '1a. Информировать пользователя о том, что мы пытаемся передать данные

 Me.Text = "Trying to send..."

 'Подождать, пока клиент не будет найден, а затем передать файл

 irdaFileSender.LoopAndAttemptIRSend()

 '1c. Информировать пользователя о том, что файл передан

 MsgBox("File sent!")

 Me.Text = "IrDA: Sent!"

 '2. Вызвать функцию в асинхронном режиме и поручить

 'передачу файла фоновому потоку

 'irdaFileSend.LoopAndAttemptIRSendAsync()

 'ПРИМЕЧАНИЕ: Если мы вызываем функцию в асинхронном режиме, то должны

 'периодически проверять, не завершила ли она выполнение, путем

 'вызова метода 'irdaFileSend.Status'

End Sub

Private Sub buttonTestFileReceive_Click(ByVal sender As Object, _

 ByVal e As EventArgs) Handles buttonTestFileReceive.Click

 'Если файл назначения уже существует, уничтожить его

 Const fileName As String = "myTestReceiveFile.txt"

 If (System.IO.File.Exists(fileName)) Then

  System.IO.File.Delete(fileName)

 End If

 Dim irdaFileReceiver As IrDAFileReceive

 irdaFileReceiver = New IrDAFileReceive(fileName, _

  myIrDASocketName)

 'Имеется 2 режима: 1 – Sync (синхронный), 2 – Async (асинхронный)

 '1. Вызвать функцию в синхронном режиме

 ' блокировать поток выполнения до тех пор, пока

 'файл не будет получен

 '1a. Информировать пользователя о том, что мы ожидаем получения файла

 Me.Text = "Waiting to receive..."

 '1b. Ожидать, пока не будет сделана попытка установления с нами связи

 'и передачи файла

 irdaFileReceiver.WaitForIRFileDownload()

 '1с. Информировать пользователя о том, что мы получили переданный файл

 Me.Text = "IrDA: received!"

 MsgBox("File received!")

 '2. Вызвать функцию в асинхронном режиме и поручить

 'получение файла фоновому потоку

 'irdaFileReceive.WaitForIRFileDownloadAsync()

 'ПРИМЕЧАНИЕ: Если мы вызываем функцию в асинхронном режиме, то должны

 'периодически проверять, не завершила ли она выполнение, путем

 'вызова метода 'irdaFileReceive.Status'

End Sub

Листинг 15.4. Класс IrDAFileSend

Option Strict On

'====================================================================

'Этот класс является клиентом IrDA. Он осуществляет поиск сервера

'IrDA, имя которого совпадает с именем службы IrDA, и после того, как

'он найден, направляет ему поток данных файла,

'====================================================================

Class IrDAFileSend

Private m_descriptionOfLastSendAttempt As String

Private m_IrDAServiceName As String

Private m_fileToSend As String

Private m_wasSenderStopped As Boolean

Public Enum SendStatus

 AttemptingToSend

 Finished_Successfully

 Finished_Aborted

 Finished_Error

End Enum

Private m_SendStatus As SendStatus

Public ReadOnly Property Status() As SendStatus

 Get

  'Блокировка выполнения параллельных операций чтения/записи в m_SendStatus

  SyncLock (Me)

   Return m_SendStatus

  End SyncLock

 End Get

End Property

Private Sub setStatus(ByVal newStatus As SendStatus)

 'Блокировка выполнения параллельных операций чтения/записи в m SendStatus

 SyncLock (Me)

  m_SendStatus = newStatus

 End SyncLock

End Sub

Public ReadOnly Property ErrorText() As String

 Get

  Return m_descriptionOfLastSendAttempt

 End Get

End Property

'–

'КОНСТРУКТОР

'–

Public Sub New(ByVal fileToSend As String, ByVal irdaServiceName As String)

 'Имя сокета IrDA, поиск которого мы хотим осуществить

 m_IrDAServiceName = irdaServiceName

 'Файл, который мы хотим передать

 m_fileToSend = fileToSend

End Sub

'–

'Запускает новый поток для осуществления попытки отправки файла

'–

Public Sub LoopAndAttemptIRSendAsync()

 'Мы находимся в режиме передачи

 setStatus(SendStatus.AttemptingToSend)

 'Пользователь пока что не отменил выполнение операции

 m_wasSenderStopped = False

 'Это функция, которую должен запустить на выполнение новый поток

 Dim threadEntryPoint As System.Threading.ThreadStart

 threadEntryPoint = _

  New System.Threading.ThreadStart(AddressOf LoopAndAttemptIRSend)

 '–

 'Создать новый поток и запустить его

 '–

 Dim newThread As System.Threading.Thread = _

  New System.Threading.Thread(threadEntryPoint)

 newThread.Start()

 'Вперед!

End Sub

'–

'Входит в цикл и пытается передать файл посредством IR

'–

Public Sub LoopAndAttemptIRSend()

 Dim irDASender As System.Net.Sockets.IrDAClient

 Dim streamOutToIrDA As System.IO.Stream

 Dim streamInFromFile As System.IO.Stream

 'Пользователь пока что не отменил выполнение операции

 m_wasSenderStopped = False

 setStatus(SendStatus.AttemptingToSend)

 '–

 'Непрерывное выполнение цикла, пока не удастся отправить сообщение

 '–

 While (True)

  'Значения всех этих переменных должны быть нулевыми до и после

  'вызова sendStream(...), если не было сгенерировано исключение!

  irDASender = Nothing

  streamOutToIrDA = Nothing

  streamInFromFile = Nothing

  'Попытаться передать поток

  Dim bSuccess As Boolean

  Try

   bSuccess = sendStream(mjdescriptionOfLastSendAttempt, _

    streamOutToIrDA, irDASender, streamInFromFile)

  Catch eUnexpected As System.Exception 'Неожиданная ошибка!!!

   setStatus(SendStatus.Finished_Error) 'Уведомить о сбое

   m_descriptionOfLastSendAttempt = _

    "Unexpected error in IR send loop. " + eUnexpected.Message

   '–

   'Освободить все распределенные нами ранее ресурсы

   '–

   If Not (streamOutToIrDA Is Nothing) Then

    Try

     streamOutToIrDA.Close()

    Catch

     'Поглотить любую ошибку

    End Try

    streamOutToIrDA = Nothing

   End If

   If Not (streamInFromFile Is Nothing) Then

    Try

     streamInFromFile.Close()

    Catch

     'Поглотить любую ошибку

    End Try

    streamInFromFile = Nothing

   End If

   If Not (irDASender Is Nothing) Then

    Try

     irDASender.Close()

    Catch

     'Поглотить любую ошибку

    End Try

    irDASender = Nothing

   End If

   Return 'Выход

  End Try

  'Проверить успешность выполнения

  If (bSuccess = True) Then

   m_descriptionOfLastSendAttempt = "Success!"

   setStatus(SendStatus.Finished Successfully)

   Return

  End If

  'Проверить, не была ли операция отменена пользователем

  If (m_wasSenderStopped = True) Then

   m_descriptionOfLastSendAttempt = "User Aborted."

   setStatus(SendStatus.Finished_Aborted)

   Return

  End If

  'В противном случае... Нам пока не удалось обнаружить сервер IrDA,

  'имя которого совпадает с именем службы. Мы продолжим выполнение цикла

  'и попытаемся найти сервер.

 End While

 'Мы никогда не попадем в это место программы при выполнении

End Sub

'–

'Попытаться передать поток ввода-вывода (например, файл) посредством IR

'[возвращаемое значение]:

' true: успешная передача файла

' false: файл не был успешно передан

'–

Private Function sendStream(ByRef errorDescription As String, _

 ByRef streamOutToIrDA As System.IO.Stream, _

 ByRef irDASender As System.Net.Sockets.IrDAClient, _

 ByRef streamInFromFile As System.IO.Stream) As Boolean

 errorDescription = ""

 '–

 'Создание нового клиента IRDA

 '–

 Try

  '–

  'Возврат произойдет довольно быстро. Клиент будет выбран

  'и возвращен, если прослушивающие клиенты отсутствуют.

  '–

  irDASender = _

   New System.Net.Sockets.IrDAClient(m_IrDAServiceName)

  Catch eCreateClient As System.Exception

   'В данном случае могли возникнуть несколько ситуаций:

   '#1: отсутствуют прослушивающие устройства

   '#2: прослушивающее устройство существует, но не реагирует

   ' (может отказаться от разговора)

   errorDescription = eCreateClient.Message

   Return False

  End Try

  'В данном случае могли возникнуть несколько ситуаций:

  '#1: Мы получили соединение от приемного устройства IR

  '#2: IR-запрос был отменен (кто-то вызвал функцию STOP).

  If (m_wasSenderStopped = True) Then

   irDASender.Close()

   irDASender = Nothing

   Return False

  End If

 '==========================================

 'ПЕРЕДАТЬ ДАННЫЕ!

 '==========================================

 'Открыть файл, который мы хотим передать

 streamInFromFile = System.IO.File.OpenRead(m_fileToSend)

 'Открыть сокет IrDA, которому мы хотим передать данные

 streamOutToIrDA = irDASender.GetStream()

 Const BUFFER_SIZE As Integer = 1024

 Dim inBuffer() As Byte

 ReDim inBuffer(BUFFER_SIZE)

 Dim bytesRead As Integer

 Dim iTestAll As Integer

 Dim iTestWrite As Integer

 ' Цикл...

 Do

  'Считать байты из файла

  bytesRead = streamInFromFile.Read(inBuffer, 0, BUFFER_SIZE)

  iTestAll = iTestAll + 1

  'Записать байты в наш выходной поток

  If (bytesRead > 0) Then

   streamOutToIrDA.Write(inBuffer, 0, bytesRead)

   iTestWrite = iTestWrite + 1

  End If

 Loop While (bytesRead > 0)

 'Сбросить выходной поток

 streamOutToIrDA.Flush() 'Закончить запись любых данных

 streamOutToIrDA.Close() 'Закрыть поток

 streamOutToIrDA = Nothing

 'Освободить локальный файл

 streamInFromFile.Close()

 streamOutToIrDA = Nothing

 'Освободить порт IrDA

 irDASender.Close()

 irDASender = Nothing

 'Успешное завершение!!!

 Return True

End Function

End Class

Листинг 15.5. Класс IrDAFileReceive

'–

'Обеспечивает прием файла через IrDA (инфракрасный порт)

'Этот класс НЕ является реентерабельным и не должен вызываться более

'чем одной функцией за один раз. Если необходимо иметь несколько

'сеансов связи через IR, это необходимо делать путем создания

'нескольких различных экземпляров данного класса.

'–

Public Class IrDAFileReceive

Private m_wasListenerStopped As Boolean

Private m_IrDAServiceName As String

Private m_fileNameForDownload As String

Private m_errorDurmgTransfer As String

Private m_irListener As System.Net.Sockets.IrDAListener

Private m ReceiveStatus As ReceiveStatus

Public ReadOnly Property ErrorText() As String

 Get

  Return m_errorDuringTransfer

 End Get

End Property

'–

'Различные состояния приема

'–

Public Enum ReceiveStatus

 NotDone_SettingUp

 NotDone_WaitingForSender

 NotDone_Receiving

 Done_Success

 Done_Aborted

 Done_ErrorOccured

End Enum

'–

' Возвращает состояние передачи

'–

Public ReadOnly Property Status() As ReceiveStatus

 Get

  SyncLock (Me)

   Return m_ReceiveStatus

  End SyncLock

 End Get

End Property

Private Sub setStatus(ByVal newStatus As ReceiveStatus)

 'Обеспечить многопоточную безопасность для предотвращения

 'параллельного выполнения операций чтения/записи

 SyncLock (Me)

  m_ReceiveStatus = newStatus

 End SyncLock 'end lock

End Sub

'–

' (in) filename: желаемое имя для входного файла IR

'–

Public Sub New(ByVal filename As String, ByVal irdaServiceName As String)

 'Имя сокета IrDA, который мы хотим открыть

 m_IrDAServiceName = irdaServiceName

 'Имя файла, в котором мы хотим сохранить полученные данные

 m_fileNameForDownload = filename

End Sub

'–

'Обеспечивает асинхронный прием файла через IR

' (in) filename: имя файла, в который осуществляется запись

'–

Public Sub WaitForIRFileDownloadAsync()

 'Заметьте, что сейчас мы находимся в режиме подготовки

 setStatus(ReceiveStatus.NotDone_SettingUp)

 '–

 'Создать новый поток

 '–

 Dim threadEntryPoint As System.Threading.ThreadStart

 threadEntryPoint = _

  New System.Threading.ThreadStart(AddressOf WaitForIRFileDownload)

 Dim newThread As System.Threading.Thread = _

  New System.Threading.Thread(threadEntryPoint)

 'Запустить поток на выполнение

 newThread.Start()

End Sub

'–

'Открывает порт IR и ожидает загрузки файла

'–

Public Sub WaitForIRFileDownload()

 Dim outputStream As System.IO.Stream

 Dim irdaClient As System.Net.Sockets.IrDAClient

 Dim irStreamIn As System.IO.Stream

 Try

  '=========================================================

  'Задать и загрузить файл!

  '=========================================================

  internal_WaitForIRFileDownload(outputStream, irdaClient, irStreamIn)

 Catch 'Поглотить любые возникающие ошибки

  setStatus(ReceiveStatus.Done_ErrorOccured)

 End Try

 '=============================================

 'Освободить все ресурсы

 '=============================================

 'Закрыть наш входной поток

 If Not (irStreamIn Is Nothing) Then

  Try

   irStreamIn.Close()

  Catch 'Поглотить любые возникающие ошибки

  End Try

 End If

 'Закрытие клиента IrDA

 If Not (irdaClient Is Nothing) Then

  Try

   irdaClient.Close()

  Catch 'Поглотить любые возникающие ошибки

  End Try

 End If

 'Закрыть файл, в который осуществлялась запись

 If Not (outputStream Is Nothing) Then

  Try

   outputStream.Close()

  Catch 'Поглотить любые возникающие ошибки

  End Try

 End If

 'Закрыть прослушивающее устройство, если оно выполняется

 If Not (m_irListener Is Nothing) Then

  'Установить первым, чтобы код, выполняющийся другим потоком,

  'был отменен, если он установлен

  m_wasListenerStopped = True

  Try

   m_irListener.Stop()

  Catch 'Поглотить любые возникающие ошибки

  End Try

  m_irListener = Nothing

 End If

End Sub

Private Sub internal_WaitForIRFileDownload( _

 ByRef outputStream As System.IO.Stream, _

 ByRef irdaClient As System.Net.Sockets.IrDAClient, _

 ByRef irStreamIn As System.IO.Stream)

 '–

 'Открыть входной файл для направления в него потока данных

 '–

 outputStream = System.IO.File.Open( _

  m_fileNameForDownload, _

  System.IO.FileMode.Create)

 '==========================================

 'ОБНОВЛЕНИЕ СОСТОЯНИЯ

 '==========================================

 setStatus(ReceiveStatus.NotDone_WaitingForSender)

 '–

 'Открыть прослушивающее устройство

 '–

 Try

  m_wasListenerStopped = False

  m_irListener = _

   New System.Net.Sockets.IrDAListener(m_IrDAServiceName)

  m_irListener.Start()

 Catch eListener As System.Exception

  m_errorDuringTransfer = "Error creating listener – " + _

   eListener.Message

  GoTo exit_sub_with_error

 End Try

 'Проверить, не поступила ли команда отменить выполнение

 If (m_wasListenerStopped = True) Then

  GoTo exit_sub_with_abort

 End If

 '–

 'Принять соединение

 '–

 Try

  '–

  'Выполнение будет приостановлено здесь до тех пор, пока устройство не

  'начнет передавать информацию, или не будет остановлен объект

  'прослушивания, выполняющийся в другом потоке)

  '–

  irdaClient = m_irListener.AcceptIrDAClient()

 Catch eClientAccept As System.Exception

  'Если прослушивание остановлено другим потоком, инициировавшим отмену

  'выполнения, будет сгенерировано исключение и управление будет

  'передано сюда.

  If (m_wasListenerStopped = True) Then

   GoTo exit_sub_with_abort

  End If

  'Если прослушивание не было прекращено,

  'то произошло иное исключение. Обработать его.

  m_errorDuringTransfer = "Error accepting connection – " + _

   eClientAccept.Message

  GoTo exit_sub_with_error

 End Try

 'В этом месте возможны два состояния:

 '#1: Мы получили соединение от передающего устройства IR

 '#2: IR-запрос был отменен (кто-то вызвал функцию STOP)

 ' (в этом случае приведенный ниже код сгенерирует исключение)

 'Проверить, не было ли отменено выполнение

 If (m_wasListenerStopped = True) Then

  GoTo exit_sub_with_abort

 End If

 '==========================================

 'ОБНОВЛЕНИЕ СОСТОЯНИЯ

 '==========================================

 setStatus(ReceiveStatus.NotDone_Receiving)

 '–

 'Открыть принимающий поток

 '–

 Try

  irStreamIn = irdaClient.GetStream()

 Catch exGetInputStream As System.Exception

  m_errorDuringTransfer = "Error getting input stream – " + _

   exGetInputStream.Message

  GoTo exit_sub_with_error

 End Try

 'Приготовиться к получению данных!

 Const BUFFER_SIZE As Integer = 1024

 Dim inBuffer() As Byte

 ReDim inBuffer(BUFFER_SIZE)

 Dim bytesRead As Integer

 Do

  'Считать байты из порта IR

  bytesRead = irStreamIn.Read(inBuffer, 0, BUFFER_SIZE)

  'Записать байты в наш выходной поток

  If (bytesRead > 0) Then

   outputStream.Write(inBuffer, 0, bytesRead)

  End If

 Loop While (bytesRead > 0)

 outputStream.Flush() 'Закончить запись любых выходных данных

 '==========================================

 'ОБНОВЛЕНИЕ СОСТОЯНИЯ: УСПЕШНО ВЫПОЛНЕНО

 '==========================================

 setStatus(ReceiveStatus.Done_Success)

 Return 'No errors

 '==========================================

 'ОШИБКА.

 '==========================================

exit_sub_with_abort:

 'ОБНОВЛЕНИЕ СОСТОЯНИЯ: Отменено (но не из-за ошибки)

 setStatus(ReceiveStatus.Done_Aborted)

 Return

exit_sub_with_error:

 'ОБНОВЛЕНИЕ СОСТОЯНИЯ: ОШИБКА!!!!

 setStatus(ReceiveStatus.Done_ErrorOccured)

 End Sub

End Class

Листинг 15.6. Простая Web-служба

'Этот код следует вставить в класс Service1, содержащийся

'в файле "Service1.asmx.vb".

'"[WebMethod]" – это атрибут метаданных, который указывает механизму

'Web-службы на то, что данный метод должен быть доступным через Web

_

Public Function AddTwoNumbers(ByVal x As Integer, _

 ByVal у As Integer) As Integer

 Return x + у

End Function

Листинг 15.7. Вызовы Web-служб с передачей параметров только явным образом

Этот код представляет собой всего лишь последовательность вызовов функций. Программистам на VB будет несложно написать его, используя в качестве образца код на С#.

Листинг 15.8. Вызов Web-служб путем неявной передачи параметров посредством cookie-файлов

Этот код представляет собой всего лишь последовательность вызовов функций. Программистам на VB будет несложно написать его, используя в качестве образца код на С#.

Листинг 15.9. Неэффективная организация диалога с Web-службой, в которой используется множество вызовов

Этот код представляет собой всего лишь последовательность вызовов функций. Программистам на VB будет несложно написать его, используя в качестве образца код на С#.

Листинг 15.10. Группирование запросов в одном вызове Web-службы

Этот код представляет собой всего лишь последовательность вызовов функций. Программистам на VB будет несложно написать его, используя в качестве образца код на С#.

Листинг 15.11. Код для загрузки файла с Web-сервера

'–

'Осуществляет синхронную загрузку файла с Web-сервера

'и сохраняет его в локальной файловой системе

'[in] httpWhereFrom: URL-адрес файла

' (например, "http://someserver/somefile.jpg")

'[in] filenameWhereTo: Место, куда необходимо записать файл

' (например, "\localfile.jpg")

'–

Public Sub downloadFileToLocalStore(ByVal httpWhereFrom As _

 String, ByVal filenameWhereTo As String)

 Dim myFileStream As System.IO.FileStream = Nothing

 Dim myHTTPResponseStream As System.IO.Stream = Nothing

 Dim myWebRequest As System.Net.WebRequest = Nothing

 Dim myWebResponse As System.Net.WebResponse = Nothing

 'Если файл, который мы хотим записать, уже существует, удалить его

 If (System.IO.File.Exists(filenameWhereTo) = True) Then

  System.IO.File.Delete(filenameWhereTo)

 End If

 Try

  'Создать Web-запрос

  myWebRequest = _

   System.Net.HttpWebRequest.Create(httpWhereFrom)

  'Получить ответ

  myWebResponse = myWebRequest.GetResponse()

  'Получить поток для ответа

  myHTTPResponseStream = myWebResponse.GetResponseStream()

  'Создать локальный файл, в который необходимо направить поток ответа

  myFileStream = System.IO.File.OpenWrite(filenameWhereTo)

  'Этот размер буфера является настраиваемым

  Const buffer_length As Integer = 4000

  Dim byteBuffer() As Byte

  ReDim byteBuffer(buffer_length)

  Dim bytesIn As Integer

  'Считать файл и направить поток данных в локальный файл

  Do

   'Считать данные

   bytesIn = myHTTPResponseStream.Read(byteBuffer, _

    0, buffer_length)

   'Записать данные

   If (bytesIn <> 0) Then

    myFileStream.Write(byteBuffer, 0, bytesIn)

   End If

  Loop While (bytesIn <> 0)

 Catch myException As Exception 'Сбой при загрузке!

  'Что-то случилось. Освободить ресурс

  attemptCleanup ThrowNoExceptions(myFileStream, _

   myHTTPResponseStream, myWebResponse)

  'Теперь, когда ресурс освобожден, повторно сгенерируем исключение,

  'чтобы сообщить приложению о том, что произошел сбой!

  Throw myException

 End Try

 'Загрузка прошла успешно!

 'Закрыть все ресурсы.

 Try

  'Стандартная процедура закрытия ресурсов.

  myFileStream.Close()

  myFileStream = Nothing

  myHTTPResponseStream.Close()

  myHTTPResponseStream = Nothing

  myWebResponse.Close()

  myWebResponse = Nothing

 Catch myException As Exception 'Сбой в процессе закрытия ресурса!

  'Что-то случилось. Освободить ресурс

  attemptCleanup_ThrowNoExceptions(myFileStream, _


    Ваша оценка произведения:

Популярные книги за неделю