Главная » C# » Создание потока, имеющего состояние в Visual C# (Sharp)

0

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

Реализация делегата Threadstart

Одним из способов выполнения потока, имеющего состояние, будет определение типа, который реализует делегат типа Threadstart. В следующем примере опредяется класс с методом, который будет вызван потоком. Применяемый метод стоит в передаче типу Thread классического делегата типа .NET 1 .х.

class ThreadedTask { string _whatToSay;

public ThreadedTask(string whatosay) {

_whatToSay = whatosay;

}

public void MethodToRun() {

Console.WriteLine("I am babbling (" + _whatToSay + ")");

}

}

Чтобы использовать метод, потоковый код модифицируется следующим образом:

ThreadedTask task = new ThreadedTask)"hello");

Thread thread = new Threadfnew Threadstart(task.MethodToRun)); thread.Start();

В примере создается экземпляр типа ThreadedTask, который имеет состояние, пле чего посредством метода statefuitask.MethodToRunо создается экземпляр Thread. При выполнении потока с членом данных _whatToSay будет ассоциировано определенное состояние. Этот код полностью логичен и не содержит никаких сюризов. Но что будет, если работающий с состояниями метод вызвать дважды, как показано в следующем коде?

ThreadedTask task = new ThreadedTask("hello") ;

Thread threadl = new Thread(new Threadstart(task.MethodToRun)); Thread thread2 = new Thread(new Threadstart(task.MethodToRun)); threadl.Start();

thread2.Start();

В данном случае мы имеем два экземпляра  Thread, но  один  экземпляр  задачи. Оба эти экземпляра будут делать одно и то же; что еще хуже — они оба будут раелять одно и то же состояние. В то время как разделение состояния в принципе не является ничем запрещенным, делать это необходимо особым образом, чтобы обеспечить целостность состояния. Поэтому нужно для каждого экземпляра Thread создать и ассоциировать с ним свой экземпляр ThreadedTask, как показано в слующем коде:

ThreadedTask taskl = new ThreadedTask("hello"); ThreadedTask task2 = new ThreadedTask("goodbye");

Thread threadl = new Thread(new Threadstart(taskl.MethodToRun)); Thread thread2 = new Thread(new Threadstart(task2.MethodToRun)); threadl.Start();

thread2.Start();

Таким образом, при выполнении метода, работающего с состоянием, необходимо ассоциировать с каждым экземпляром потока свой экземпляр задачи. Это означает, что в таком случае мы не может использовать анонимные подставляемые в коде (in-line) методы, которые обращаются к состоянию. Вместо этого нужно использать решение, показанное в  разд.  "Использование  лямбда-выражений  в  электроой  таблице" главы  11.

Использование параметров потока

Допустим, что мы хотим использовать подставляемый анонимный метод или лямбда-выражение, а также поток с состоянием. Это можно сделать с помощью параметров потока. Параметры потока подобны параметрам метода, только данные передаются экземпляру потока, и его можно рассматривать, как конструктор пота. Далее приводится пример параметра потока:

Thread thread = new Thread(

(buffer) => { Console.WriteLine("You said (" + buffer.ToString() + ")");

}) ;

thread.Start("my text");

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

На использование параметров потока накладываются два ограничения: можно педавать только один параметр и этот параметр должен быть объектом.

ПРИМЕЧАНИЕ

Хотя возможность передавать лишь один параметр и представляет  неудобство,  это все-таки лучше, чем ни одного. Но то, что этот параметр  должен  быть  объектом,  не совсем понятно, т.  к.  у  нас  имеются  обобщения  .NET.  Тем  не  менее,  таковы  ограничия  на  использование  параметров  потока,  и  с  ними  нужно  считаться.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии