Я реализую метод Task<Result> StartSomeTask()
и знаю результат еще до вызова метода. Как мне создать Task <T> , который уже выполнен?
Вот чем я сейчас занимаюсь:
private readonly Result theResult = new Result();
public override Task<Result> StartSomeTask()
{
var task = new Task<Result>(() => theResult);
task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
return task;
}
Есть ли лучшее решение?
ValueTask
для завершенных задач (т.е. для значений, которые у вас уже есть, так что код по существу синхронный), что сэкономит вам выделение.Ответы:
источник
При ориентации на .NET 4.5 вы можете использовать
Task.FromResult
:Чтобы создать неудавшуюся задачу, используйте
Task.FromException
:.NET 4.6 добавляет,
Task.CompletedTask
если вам нужен не общийTask
.Обходные пути для более старых версий .NET:
При ориентации на .NET 4.0 с помощью Async Targetting Pack (или AsyncCTP) вы можете использовать
TaskEx.FromResult
вместо этого.Чтобы получить неуниверсальный пакет
Task
до .NET 4.6, вы можете использовать тот факт, который являетсяTask<T>
производным отTask
и просто вызватьTask.FromResult<object>(null)
илиTask.FromResult(0)
.источник
FromException
метод, который ведет себя как,FromResult
но вместо этого представляет собой некорректную задачу. Такой метод может просто возвращать это для своих случаев ошибок, если важно, чтобы исключение было представлено в результирующей задаче.Для задач без возвращаемого значения в .NET 4.6 добавлен Task.CompletedTask .
Он возвращает задачу, которая уже находится в TaskStatus.RanToCompletion. Вероятно, он каждый раз возвращает один и тот же экземпляр, но документация предупреждает, что не стоит рассчитывать на этот факт.
источник
Если вы используете Rx, альтернативой является Observable.Return (result) .ToTask ().
источник
Вызов Task.WhenAll без каких-либо параметров вернет завершенную задачу.
источник