Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 72 73 74 75 76 77 78 79 80 ... 206
Перейти на страницу:

  //Рабочие состояния

  //-----------------

  //Ожидание запуска фонового потока

  waitingToStartAsync,

  //Выполнение кода в фоновом потоке

  running,

  //Запросить отмену выполнения вычислений

  requestAbort,

  //--------------------

  //Состояния завершения

  //--------------------

  //Состояние завершения: выполнение фонового потока

  //успешно завершено

  done,

  //Состояние завершения: выполнение потока отменено

  //до его завершения

  aborted

 }

 ProcessingState m_processingState;

 public delegate void ExecuteMeOnAnotherThread(ThreadExecuteTask checkForAborts);

 private ExecuteMeOnAnotherThread m_CallFunction;

 private object m_useForStateMachineLock;

 public ThreadExecuteTask(ExecuteMeOnAnotherThread functionToCall) {

  //Создать объект, который мы можем использовать

  //в конечном автомате в целях блокировки

  m_useForStateMachineLock = new Object();

  //Обозначить готовность к началу выполнения

  m_processingState = ProcessingState.notYetStarted;

  //Сохранить функцию, которую необходимо вызвать

  //в новом потоке

  m_CallFunction = functionToCall;

  //----------------------------------------------------------

  //Создать новый поток и вызвать в нем функцию на выполнение:

  // this.ThreadStartPoint()

  //----------------------------------------------------------

  System.Threading.ThreadStart threadStart;

  threadStart = new System.Threading.ThreadStart(ThreadStartPoint);

  System.Threading.Thread newThread;

  newThread = new System.Threading.Thread(threadStart);

  //Обозначить готовность к началу выполнения (в целях определенности

  //это важно сделать еще до того, как будет запущен поток!)

  setProcessingState(ProcessingState.waitingToStartAsync);

  //Дать ОС команду начать выполнение нового потока в асинхронном режиме

  newThread.Start();

  //Возвратить управление функции, вызывающей этот поток

 }

 //---------------------------------------------

 //Эта функция является точкой входа, вызываемой

 //для выполнения в новом потоке

 //---------------------------------------------

 private void ThreadStartPoint() {

  //Установить состояние обработки, соответствующее

  //выполнению функции в новом потоке!

  setProcessingState(ProcessingState.running);

  //Запустить на выполнение пользовательский код и передать указатель в

  //наш класс, чтобы этот код мог периодически проверять, не поступил ли

  //запрос на прекращение выполнения

  m_CallFunction(this);

  //Если выполнение не было отменено, изменить состояние таким образом,

  //чтобы оно соответствовало успешному завершению

  if (m_processingState != ProcessingState.aborted) {

   //Обозначить завершение выполнения

   setProcessingState(ProcessingState.done);

  }

  //Выйти из потока...

 }

 //----------------

 //Конечный автомат

 //----------------

 public void setProcessingState(ProcessingState nextState) {

  //B любой момент времени только одному потоку выполнения

  //могут быть разрешены попытки изменить состояние

  lock(m_useForStateMachineLock) {

   //B случае попытки повторного вхождения в текущее состояние

   //никакие дополнительные действия не выполняются

   if (m_processingState == nextState) {

    return;

   }

   //------------------------------------------------------

   //Простейший защитный код, гарантирующий

   //невозможность перехода в другое состояние, если задача

   //либо успешно завершена, либо успешно отменена

   //------------------------------------------------------

   if ((m_processingState == ProcessingState.aborted) ||

       (m_processingState == ProcessingState.done)) {

    return;

   }

   //Убедиться в допустимости данного изменения состояния

   switch (nextState) {

   case ProcessingState.notYetStarted:

    throw new Exception("Переход в состояние 'notYetStarted' невозможен");

   case ProcessingState.waitingToStartAsync:

    if (m_processingState != ProcessingState.notYetStarted) {

     throw new Exception("Недопустимое изменение состояния");

    }

    break;

   case ProcessingState.running:

    if (m_processingState != ProcessingState.waitingToStartAsync) {

     throw new Exception("Недопустимое изменение состояния");

    }

    break;

   case ProcessingState.done:

    //Мы можем завершить работу лишь тогда, когда она выполняется.

    //Это возможно также в тех случаях, когда пользователь затребовал

    //отмену выполнения, но работа к этому моменту уже была закончена

    if ((m_processingState != ProcessingState.running) &&

       (m_processingState != ProcessingState.requestAbort)) {

     throw new Exception("Недопустимое изменение состояния");

    }

    break;

   case ProcessingState.aborted:

    if (m_processingState != ProcessingState.requestAbort) {

     throw new Exception("Недопустимое изменение состояния");

    }

    break;

   }

   //Разрешить изменение состояния

   m_processingState = nextState;

  }

 }

 public ProcessingState State {

  get {

   ProcessingState currentState;

   //Предотвратить попытки одновременного чтения/записи состояния

   lock(m_useForStateMachineLock) {

    currentState = m_processingState;

   }

   return currentState;

  }

 }

} //Конец класса

В листинге 9.2 представлен код, имитирующий выполнение работы фоновым потоком. Когда фоновый поток начинает выполнять код, на экране отображается окно сообщения. Выполнение работы имитируется созданием серии пауз длительностью в одну треть секунды, в промежутках между которыми рабочий код проверяет, не поступил ли от другого потока запрос на прекращение выполнения.

Листинг 9.2. Тестовая программа для выполнения работы в фоновом потоке

using System;

//-------------------------------------------------

//Тестовый код, который используется для выполнения

//фоновым потоком

//-------------------------------------------------

public class Test1 {

 public int m_loopX;

 //------------------------------------------------------------------

 //Функция, вызываемая фоновым потоком

 // [in] threadExecute: Класс, управляющий выполнением нашего потока.

 // Мы можем контролировать его для проверки

 // того, не следует ли прекратить вычисления

 //------------------------------------------------------------------

 public void ThreadEntryPoint(ThreadExecuteTask threadExecute) {

  //Это окно сообщений будет отображаться в контексте того потока,

  //в котором выполняется задача

  System.Windows.Forms.MessageBox.Show("Выполнение ТЕСТОВОГО ПОТОКА");

  //------

  //60 раз

  //------

  for (m_loopX = 0; m_loopX < 60; m_loopX++) {

   //Если затребована отмена выполнения, мы должны завершить задачу

   if (threadExecute.State == ThreadExecuteTask.ProcessingState.requestAbort) {

    threadExecute.setProcessingState(ThreadExecuteTask.ProcessingState.aborted);

    return;

   }

   //Имитировать выполнение работы: пауза 1/3 секунды

   System.Threading.Thread.Sleep(333);

  }

 }

} //Конец класса

В листинге 9.3 содержится код, который можно запустить на выполнение из основного потока пользовательского интерфейса с целью активизации и контроля фоновой обработки. Этот код не является независимым классом и должен помещаться в форму, с кнопками которой должны быть связаны события щелчков на кнопках.

Листинг 9.3. Код для запуска и тестирования приведенного выше тестового кода

//Класс, который будет управлять выполнением нового потока

private ThreadExecuteTask m_threadExecute;

//Класс, метод которого мы хотим выполнять в асинхронном режиме

Test1 m_testMe;

//----------------------------------------------------------

//Этот код должен быть запущен ранее другого кода, поскольку

//он запускает новый поток выполнения!

//

//Создать новый поток и обеспечить его выполнение

//----------------------------------------------------------

private void buttonStartAsyncExecution_Click(object sender, System.EventArgs e) {

 //Создать экземпляр класса, метод которого мы хотим вызвать

 //в другом потоке

 m_testMe = new Test1();

1 ... 72 73 74 75 76 77 78 79 80 ... 206
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре.
Комментарии