Возвращает пустую статическую задачу в TPL плохую практику?

Есть случаи, когда я хотел бы выполнить задачу условно. Я использую какой-то метод расширения следующим образом:

public static class MyTaskExtension{
  private static Task theEmptyTask = Task.Factory.StartNew(() => {}); //This is the question

  public static Task ContinueWith(this Task task, Task continuationTask, Func<bool> condition)
  {
    if condition(){
       ... do the work
    }
    return theEmptyTask;
  }
}

Я ожидаю, что theEmptyTask уже будет завершен, поэтому в основном, если я не хочу ничего делать, я просто возвращаю эту задачу вместо пустой или новой пустой задачи.

У меня такое чувство, что с этим подходом должен быть какой-то сбой. Кто-нибудь может это увидеть?

Ответы

Ответ 1

Совершенно приемлемо возвращать уже выполненную задачу в некоторых контекстах. Это не то, что делается особенно часто, но это делается.

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

Обратите внимание, что если вы хотите вернуть уже выполненную задачу, вы можете использовать Task.FromResult для генерации одного с меньшими накладными расходами, чем то, что вы сейчас делаете, поскольку вы не будете создавать пустой метод, планируя его, ожидая он должен быть запущен, а затем сразу закончите. Просто возврат Task.FromResult(false) даст вам уже выполненную задачу.

Если вы используете .NET 4.0, вы можете создать свой собственный FromResult достаточно легко:

public static Task FromResult<T>(T result)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(result);
    return tcs.Task;
}

Ответ 2

Пока вы возвращаете задачу, которая находится в завершенном состоянии (используйте TaskCompletionSource для этого), я не могу придумать никаких проблем с этим, так как на Task класс, который позволит клиенту гасить с вашей статической пустой задачей. Они могли бы называть Dispose() вашей задачей, но я не думаю, что это навредит (т.е. Я не думаю, что это повлияет на способность проверять свойства Задачи (не пробовал - что-то стоит проверить)).