public void Dispose()
Метод Dispose()
реализуется в классе Task
, освобождая ресурсы, используемые этим классом. Как правило, ресурсы, связанные с классом Task
, освобождаются автоматически во время "сборки мусора" (или по завершении программы). Но если эти ресурсы требуется освободить еще раньше, то для этой цели служит метод Dispose()
. Это особенно важно в тех программах, где создается большое число задач, оставляемых на произвол судьбы.
Следует, однако, иметь в виду, что метод Dispose()
можно вызывать для отдельной задачи только после ее завершения. Следовательно, для выяснения факта завершения отдельной задачи, прежде чем вызывать метод Dispose()
, потребуется некоторый механизм, например, вызов метода Wait()
. Именно поэтому так важно было рассмотреть метод Wait()
, перед тем как обсуждать метод Dispose()
. Ели же попытаться вызвать Dispose()
для все еще активной задачи, то будет сгенерировано исключение InvalidOperationException
.
Во всех примерах, приведенных в этой главе, создаются довольно короткие задачи, которые сразу же завершаются, и поэтому применение метода Dispose()
в этих примерах не дает никаких преимуществ. (Именно по этой причине вызывать метод Dispose()
в приведенных выше программах не было никакой необходимости. Ведь все они завершались, как только завершалась задача, что в конечном итоге приводило к освобождению от остальных задач.) Но в целях демонстрации возможностей данного метода и во избежание каких-либо недоразумений метод Dispose()
будет вызываться явным образом при непосредственном обращении с экземплярами объектов типа Task
во всех последующих примерах программ. Если вы обнаружите отсутствие вызовов метода Dispose()
в исходном коде, полученном из других источников, то не удивляйтесь этому. Опять же, если программа завершается, как только завершится задача, то вызывать метод Dispose()
нет никакого смысла — разве что в целях демонстрации его применения.
Применение класса TaskFactory для запуска задачи
Приведенные выше примеры программы были составлены не так эффективно, как следовало бы, поскольку задачу можно создать и сразу же начать ее исполнение, вызвав метод StartNew()
, определенный в классе TaskFactory
. В классе TaskFactory
предоставляются различные методы, упрощающие создание задач и управление ими. По умолчанию объект класса TaskFactory
может быть получен из свойства Factory
, доступного только для чтения в классе Task
. Используя это свойство, можно вызвать любые методы класса TaskFactory
. Метод StartNew()
существует во множестве форм. Ниже приведена самая простая форма его объявления:
public Task StartNew(Action action)
где StartNew()
автоматически создается экземпляр объекта типа Task
для действия, определяемого параметром 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() {