Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Требования к методу, передаваемому в пул потоков
Метод, передаваемый потоку, отвечает обычным требованиям. Во-первых, это может быть void метод с одним параметром типа object, т.е. метод, принадлежащий классу, задаваемому делегатом WaitCallback. Если методу не нужно передавать информацию, то в момент вызова фактический параметр, соответствующий параметру obj, просто не задается. Если же нужно передать информацию, то фактический параметр может быть объектом, содержащим всю необходимую информацию. Естественно, что в этом случае в методе, прежде чем использовать информацию, необходимо привести параметр obj к требуемому типу. Еще одна возможность состоит в том, чтобы передать потоку не просто метод, а объект, вызывающий метод с требуемой сигнатурой. Тогда вся требуемая методу информация может содержаться в полях объекта. Этот способ передачи данных при работе с потоками, как мы знаем, является одним из наиболее надежных. Ну и наконец, можно передать потоку анонимный метод. Преимущество этого способа в том, что в этом случае анонимный метод может вызывать метод с произвольной сигнатурой. Вот как происходит связывание определяющего задачу метода с потоком из пула. У класса ThreadPool есть статический метод QueueUserWorkItem, позволяющий поставить задачу в очередь на выполнение. Метод является функцией, возвращающей true, если задача успешно поставлена в очередь, и false - в противном случае. Метод перегружен. Ему можно передавать один или два параметра. Первым параметром является объект класса WaitCallback, представляющий передаваемый потоку метод. Вторым параметром, если он задан, является объект универсального класса object. Первый параметр несет информацию о методе, передаваемом потоку, второй - содержит информацию, передаваемую методу, являясь фактическим параметром метода. ThreadPool.QueueUserWorkItem(WorkerOne); object inf = new Info(" Феликс", 50); ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerTwo), inf); ThreadPool.QueueUserWorkItem((name) => { WorkerThree(" Дмитрий"); }); Simple sim = new Simple(" Олег", 33, " программист"); ThreadPool.QueueUserWorkItem(new WaitCallback(sim.About)); object inf_add = " Прекрасный работник"; ThreadPool.QueueUserWorkItem(new WaitCallback(sim.About), inf_add); Здесь вначале создается объект sim класса Simple. Затем пулу потоков передается этот объект, вызывающий метод About из класса Simple. Операция выполняется дважды, во втором случае помимо информации, содержащейся в самом вызывающем объекте sim, метод может использовать информацию, передаваемую через параметр inf_add. Рассмотрим текст класса Simple: class Simple { string name; int age; string profession; public Simple(string name, int age, string profession) { this.name = name; this.age = age; this.profession = profession; } public void About(object inf) { Console.WriteLine(" Новый работник. Мое имя - {0}, " + " возраст - {1} профессия - {2}", name, age, profession); if (inf! = null) Console.WriteLine(inf.ToString()); } } В результате приведенных фрагментов кода в очередь к пулу потоков поставлены пять наших задач. Осталось синхронизировать работу потоков из пула потоков и основного потока, выполняющего процедуру Main. Рассмотрим простейший способ синхронизации, когда основной поток засыпает на некоторое время, давая шанс на выполнение потокам в фоновом режиме. Вот как выглядит заключительный фрагмент процедуры Main, работающий после того, как задачи поставлены в очередь к пулу потоков: //Основной поток засыпает //В это время потоки пула выполняются Thread.Sleep(100);
//Основной поток проснулся и продолжил работу Console.WriteLine(" Я управляющий! ");
|