Создание обертки задачи вокруг существующего объекта
У меня есть метод, который возвращает задачу, для реализации которой может потребоваться или не понадобиться выполнить медленную операцию, чтобы получить результат. Я хотел бы просто обвести значение результата в задачу, которая помечена как синхронно завершена в случае, когда значение уже доступно. Сегодня у меня есть что-то вроде этого:
public Task<Foo> GetFooAsync(int key) {
lock(this) {
if(_Cache.ContainsKey(key) ) {
Task<Foo> ret = new Task<Foo>(()=>_Cache[key]);
ret.RunSynchronously();
return ret;
}
else {
return Task.Factory.StartNew<Foo>(SomethingSlow());
}
}
}
Существует ли более простой способ сделать это, что не требует от меня задания задачи с делегатом, когда я уже знаю результат?
Ответы
Ответ 1
Вы можете использовать TaskCompletionSource<TResult>
:
var tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(_Cache[key]);
return tcs.Task;
(Обратите внимание, что если _Cache
является Dictionary<TKey, TValue>
, вы можете использовать TryGetValue
, чтобы сделать его единственным поиском.)
Ответ 2
Начиная с .NET 4.5, вы можете использовать статический метод Task.FromResult<T>()
именно для этой цели:
return Task.FromResult(_Cache[key]);
Ответ 3
Если у вас есть синхронная версия метода, который возвращает результат, вы можете сделать следующее
Task<String>(()=> Hello(Name));
Метод hello будет выглядеть ниже.
public String Hello(String Name)
{
return "Hello " + Name;
}