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