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

  setProcessingState(ProcessingState.waitingToStartAsync);

  newThread.Start();

 }

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

 //Основной рабочий поток. Этот поток запускает поиск очередного

 //простого числа и выполняется до тех пор, пока не произойдет

 //одно из следующих двух событий:

 // (а) найдено очередное простое число

 // (b) от внешнего (по отношению к данному) потока поступила

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

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

 public void findNextHighestPrime() {

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

  //даже не должен начинаться

  if (m_processingState == ProcessingState.requestAbort) {

   goto finished_looking;

  }

  //Состояние должно отвечать, что поиск продолжается

  setProcessingState(ProcessingState.lookingForPrime);

  long currentItem;

  //Проверить, является ли число нечетным

  if ((m_startPoint & 1) == 1) {

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

   currentItem = m_startPoint + 2;

  } else {

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

   currentItem = m_startPoint + 1;

  }

  //Приступить к поиску простого числа

  while (m_processingState == ProcessingState.lookingForPrime) {

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

   if (isItemPrime(currentItem) == true) {

    m_NextHighestPrime = currentItem; //Обновить состояние

    setProcessingState(ProcessingState.foundPrime);

   }

   currentItem = currentItem + 2;

  }

finished_looking:

  //Выход. К этому моменту либо от другого потока поступила

  //команда прекратить поиск, либо было найдено и записано

  //следующее наибольшее простое число

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

  //сообщить, что выполнение процесса прекращено

  if (m_processingState == ProcessingState.requestAbort) {

   setProcessingState(ProcessingState.aborted);

  }

 }

 //Вспомогательная функция, которая проверяет, является

 //ли число простым

 private bool isItemPrime(long potentialPrime) {

  //Если число — четное, значит, оно не является простым

  if ((potentialPrime & 1) == 0) {

   return false;

  }

  //Продолжать поиск до тех пор, пока не будет превышено

  //значение квадратного корня из числа

  long end_point_of_search;

  end_point_of_search = (long)System.Math.Sqrt(potentialPrime) + 1;

  long current_test_.item = 3;

  while (current_test_item <= end_point_of search) {

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

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

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

   if (m_processingState != ProcessingState.lookingForPrime) {

    return false;

   }

   //Если число делится без остатка,

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

   if (potentialPrime % current_test_item == 0) {

    return false;

   }

   //увеличить число на два

   current_test item = current_test_item + 2;

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

   //Увеличить количество проверенных элементов

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

   //ПРИМЕЧАНИЕ. Мы используем блокирование потока для уверенности в том,

   //что эти значения не считываются во время выполнения операции

   //их записи. Поскольку доступ к m_comparisonsSoFar

   //и m_CurrentNumberBeingExamined могут осуществлять

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

   //операция записи/считывания должна синхронизироваться с "блокировкой",

   //что будет гарантировать "атомарность" этих операций

   lock(this) {

    m_CurrentNumberBeingExamined = potentialPrime;

    m_comparisonsSoFar++;

   }

  }

  //Число является простым

  return true;

 } //Конец функции

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

Резюме 

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

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