Применение класса TaskFactory для запуска задачи



 

Приведенные выше примеры программы были составлены не так эффективно, как следовало бы, поскольку задачу можно создать и сразу же начать ее исполнение, вызвав метод StartNew(), определенный в классе TaskFactory. В классе TaskFactory предоставляются различные методы, упрощающие создание задач и управление ими. По умолчанию объект класса TaskFactory может быть получен из свойства Factory, доступного только для чтения в классе Task. Используя это свойство, можно вызвать любые методы класса TaskFactory. Метод StartNew() существует во множестве форм. Ниже приведена самая простая форма его объявления:

 

Public Task StartNew(Action action)

 

где action — точка входа в исполняемую задачу. Сначала в методе StartNew() автоматически создается экземпляр объекта типа Task для действия, определяемого параметром action , а затем планируется запуск задачи на исполнение. Следовательно, необходимость в вызове метода Start() теперь отпадает.

Например, следующий вызов метода StartNew() в рассматривавшихся ранее программах приведет к созданию и запуску задачи tsk одним действием.

 

Task tsk = Task.Factory.StartNew(MyTask);

 

После этого оператора сразу же начнет выполняться метод MyTask().

Метод StartNew() оказывается более эффективным в тех случаях, когда задача создается и сразу же запускается на исполнение. Поэтому именно такой подход и применяется в последующих примерах программ.

 

 

Применение лямбда-выражения в качестве задачи

 

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

В приведенном ниже примере программы демонстрируется применение лямбда-выражения в качестве задачи. В этой программе код метода MyTask() из предыдущих примеров программ преобразуется в лямбда-выражение.

 

// Применить лямбда-выражение в качестве задачи.

using System;

using System.Threading;

using System.Threading.Tasks;

 

class DemoLambdaTask {

static void Main() {

Console.WriteLine("Основной поток запущен.");

 

Далее лямбда-выражение используется для определения задачи.

Task tsk = Task.Factory.StartNew(() => {

Console.WriteLine("Задача запущена");

for (int count = 0; count < 10; count++) {

Thread.Sleep(500);

Console.WriteLine("Подсчет в задаче равен " + count );

}

Console.WriteLine("Задача завершена");

} );

 

Ожидать завершения задачи tsk.

tsk.Wait();

Освободить задачу tsk.

tsk.Dispose();

 

Console.WriteLine("Основной поток завершен.");

}

}

 

Ниже приведен результат выполнения этой программы.

 

Основной поток запущен.

Задача запущена

Подсчет в задаче равен 0

Подсчет в задаче равен 1

Подсчет в задаче равен 2

Подсчет в задаче равен 3

Подсчет в задаче равен 4

Подсчет в задаче равен 5

Подсчет в задаче равен 6

Подсчет в задаче равен 7

Подсчет в задаче равен 8

Подсчет в задаче равен 9

Задача завершена

Основной поток завершен.

 

Помимо применения лямбда-выражения для описания задачи, обратите также внимание в данной программе на то, что вызов метода tsk.Dispose() не делается до тех пор, пока не произойдет возврат из метода tsk.Wait(). Как пояснялось в предыдущем разделе, метод Dispose() можно вызывать только по завершении задачи. Для того чтобы убедиться в этом, попробуйте поставить вызов метода tsk.Dispose() в рассматриваемой здесь программе перед вызовом метода tsk.Wait(). Вы сразу же заметите, что это приведет к исключительной ситуации.

 

 

Создание продолжения задачи

 

Одной из новаторских и очень удобных особенностей библиотеки TPL является возможность создавать продолжение задачи. Продолжение — это одна задача, которая автоматически начинается после завершения другой задачи. Создать продолжение можно, в частности, с помощью метода ContinueWith(), определенного в классе Task. Ниже приведена простейшая форма его объявления:

 

public Task ContinueWith(Action<Task> действие_продолженмя)

 

где действие_продолжения обозначает задачу, которая будет запущена на исполнение по завершении вызывающей задачи. У делегата Action имеется единственный параметр типа Task. Следовательно, вариант делегата Action, применяемого в данном методе, выглядит следующим образом.

 

public delegate void Action<in T>(T obj)  

 

В данном случае обобщенный параметр Т обозначает класс Task.

Продолжение задачи демонстрируется на примере следующей программы.

 

// Продемонстрировать продолжение задачи.  

using System;  

using System.Threading;  

using System.Threading.Tasks;  

 

class ContinuationDemo {  


Дата добавления: 2019-02-12; просмотров: 275; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!