Потоки для асинхронных
вычислительных операций
В этом разделе я покажу, как создать поток и заставить его исполнить асинхронную
вычислительную операцию. При этом я не рекомендую пользоваться приемами,
описываемыми в этом разделе (а для приложений Windows Store они и вовсе не-
возможны из-за недоступности класса
System.Thread
). По возможности для этой
цели лучше прибегать к доступному в CLR
пулу потоков
(thread pool). О нем мы
поговорим в следующей главе.
Возможны ситуации, когда требуется явно создать поток для выполнения кон-
кретной вычислительной операции. Обычно такая необходимость возникает при
выполнении кода, приводящего поток в состояние, отличное от обычного состояния
потока из пула. К примеру:
735
Потоки.для.асинхронных.вычислительных.операций
Поток требуется запустить с нестандартным приоритетом (все потоки пула
выполняются с обычным приоритетом). Хотя изменить приоритет можно, но
делать это не рекомендуется, кроме того, изменение приоритета не сохраняется
между операциями с пулом потоков.
Чтобы приложение не закрылось до завершения потоком задания, требуется,
чтобы поток исполнялся в фоновом режиме. Эта тема подробно рассмотрена
в разделе «Фоновые и активные потоки» далее в этой главе. Потоки из пула
всегда являются фоновыми, и существует риск, что они не успеют выполнить
задание из-за того, что CLR решит завершить процесс.
Задания, связанные с вычислениями, обычно выполняются крайне долго; для
подобных заданий я не стал бы отдавать решение о необходимости создания
нового потока на откуп логике пула потоков.
Возможно возникнет необходимость преждевременно завершить исполняю-
щийся поток методом
Abort
класса
Thread
, который был подробно рассмотрен
в главе 22.
Для создания выделенного потока вам потребуется экземпляр класса
System.
Threading.Thread
, для получения которого следует передать конструктору имя
метода. Вот прототип такого конструктора:
public sealed class Thread : CriticalFinalizerObject, ... {
public Thread(ParameterizedThreadStart start);
// Здесь не показаны редко используемые конструкторы
}
Параметр
start
задает метод, который будет выполняться в выделен-
ном потоке. Сигнатура этого метода должна совпадать с сигнатурой делегата
ParameterizedThreadStart
:
1
delegate void ParameterizedThreadStart(Object obj);
Создание объекта
Thread
является достаточно простой операцией, так как при
этом физический поток в операционной системе не появляется. Для создания
физического потока, призванного исполнить метод обратного вызова, следует
воспользоваться методом
Start
класса
Thread
, передав в него объект (состояние),
который вы хотите сделать аргументом метода обратного вызова. Следующий код
демонстрирует процедуру создания выделенного потока, который затем асинхронно
вызывает метод:
1
Класс Thread также предлагает конструктор, принимающий делегат ThreadStart, который
не имеет аргументов и не возвращает значений. Но лично я не рекомендую их использовать
из-за многочисленных ограничений. Если метод вашего потока принимает класс Object и
возвращает значение типа void, вызовите его при помощи выделенного потока или пула
потока, как показано в главе 27.
736
Do'stlaringiz bilan baham: |