В приведенном ниже примере программы демонстрируется применение лямбда-выражения в качестве задачи. В этой программе код метода 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("Основной поток завершен.");
}
}
Ниже приведен результат выполнения этой программы.
Основной поток запущен.
Задача завершена Основной поток завершен.
Помимо применения лямбда-выражения для описания задачи, обратите также внимание в данной программе на то, что вызов метода tsk. Dispose () не делается до тех пор, пока не произойдет возврат из метода tsk. Wait (). Как пояснялось в предыдущем разделе, метод Dispose () можно вызывать только по завершении задачи. Для того чтобы убедиться в этом, попробуйте поставить вызов метода tsk. Dispose () в рассматриваемой здесь программе перед вызовом метода tsk .Wait (). Вы сразу же заметите, что это приведет к исключительной ситуации.
Создание продолжения задачи
Одной из новаторских и очень удобных особенностей библиотеки TPL является возможность создавать продолжение задачи. Продолжение — это одна задача, которая автоматически начинается после завершения другой задачи. Создать продолжение можно, в частности, с помощью метода ContinueWith (), определенного в классе Task. Ниже приведена простейшая форма его объявления:
public Task ContinueWith(Action действие_продолженмя)
где действие_продолжения обозначает задачу, которая будет запущена на исполнение по завершении вызывающей задачи. У делегата Action имеется единственный параметр типа Task. Следовательно, вариант делегата Action, применяемого в данном методе, выглядит следующим образом.
public delegate void Action(T obj)
В данном случае обобщенный параметр Т обозначает класс Task.
Продолжение задачи демонстрируется на примере следующей программы.
// Продемонстрировать продолжение задачи.
using System;
using System.Threading;
using System.Threading.Tasks;
class ContinuationDemo {
// Метод, исполняемый как задача, static void MyTaskO {
Console.WriteLine("MyTask() запущен");
for(int count = 0; count < 5; count++) {
Thread.Sleep(500);
Console.WriteLine("В методе MyTaskO подсчет равен " + count );
}
Console.WriteLine("MyTask завершен");
}
// Метод, исполняемый как продолжение задачи, static void ContTask(Task t) {
Console.WriteLine("Продолжение запущено");
for(int count = 0; count < 5; count++) {
Thread.Sleep(500);
Console.WriteLine("В продолжении подсчет равен " + count );
}
Console.WriteLine("Продолжение завершено");
}
static void Main() {
Console.WriteLine("Основной поток запущен.");
// Сконструировать объект первой задачи.
Task tsk = new Task(MyTask);
//А теперь создать продолжение задачи.
Task taskCont = tsk.ContinueWith(ContTask);
// Начать последовательность задач, tsk.Start () ;
// Ожидать завершения продолжения. taskCont.Wait();
tsk.Dispose(); taskCont.Dispose();
Console.WriteLine("Основной поток завершен.");
}
}
Ниже приведен результата выполнения данной программы.
Основной поток запущен.
MyTas к() запущен
В методе MyTaskO подсчет равен 0
MyTask() завершен Продолжение запущено В продолжении подсчет равен О В продолжении подсчет равен 1 В продолжении подсчет равен 2 В продолжении подсчет равен 3 В продолжении подсчет равен 4 Продолжение завершено Основной поток завершен.
Читать дальше