Создание завершенной задачи



Я хочу создать завершенный Task (не Task<T>). Есть ли что-то встроенное в .NET для этого?



соответствующий вопрос:
создать завершенную задачу

773   8  

8 ответов:

на новейшая версия .Net (v4.6) добавить только, что встроенный задач.CompletedTask:

Task completedTask = Task.CompletedTask;

это свойство реализуется как синглтон без блокировки, так что вы бы почти всегда используйте одну и ту же выполненную задачу.

Task<T> неявно преобразуется в Task, Так что просто получить заполненную Task<T>T и любое значение) и использовать это. Вы можете использовать что-то вроде этого, чтобы скрыть тот факт, что реальный результат есть, где-то.

private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
    return completedTask;
}

обратите внимание, что поскольку мы не раскрываем результат, а задача всегда завершена, мы можем кэшировать одну задачу и повторно использовать ее.

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

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

мой предпочтительный метод для этого-вызвать Task.WhenAll() без аргументов. Элемент Примечание заявляет, что "если предоставленный массив/перечисляемый не содержит задач, возвращенная задача немедленно перейдет в состояние RanToCompletion, прежде чем она будет возвращена вызывающему объекту.". Это звучит как то, что вы хотите.

обновление: я нашел источник на источник ссылки Microsoft; там вы можете увидеть эту задачу.WhenAll содержит следующее:

return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
            Task.CompletedTask :
            new WhenAllPromise(tasks);

Поэтому Задачу.CompletedTask действительно является внутренним, но он открывается вызовом WhenAll() без аргументов.

Я хотел бы использовать Task.Delay(0). Внутренне, он возвращает кэшированный экземпляр заполненной Task<T>. Это именно то, что текущий ответ предлагает делать в любом случае, только теперь вам не нужно кэшировать экземпляр самостоятельно, и у вас нет никаких неэлегантных значений мусора в вашем коде.

возможно, вы думаете, что можете использовать Task.Yield() вместо этого, но получается результат Task.Yield() и не подтипом Task, то результатом Task.Delay(0) есть. Это один из тонких различия между ними.

можно использовать задач.FromResult (в .NET 4.5) для возврата завершенного Task<T>.

Если вам нужен не общий Task, вы всегда можете использовать Task.FromResult(0) или подобное, так как Task<T> является наследником Task.

для .Net 4.6 и выше используйте

return Task.CompletedTask;

для более низкой версии вы можете использовать

return new Task(() => { });

можно использовать Нито.AsyncEx.TaskConstants.Завершено из большой библиотеки AsyncEx С Стивен Клири.

Как насчет:

#pragma warning disable 1998
    public async Task emptyTask() {
    }
#pragma warning restore 1998

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

Comments

    Ничего не найдено.