Создание обёртки задачи вокруг существующего объекта - PullRequest
11 голосов
/ 14 января 2011

У меня есть метод, который возвращает задачу, в которой реализации может потребоваться или не потребоваться выполнить медленную операцию для получения результата.Я хотел бы иметь возможность просто обернуть значение результата в Задачу, которая помечена как выполненная синхронно в случае, если значение уже доступно.Сегодня у меня есть что-то вроде этого:

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());
    }
  }
}

Есть ли более простой способ сделать это, не требующий от меня создания задачи с делегатом, когда я уже знаю результат?

Ответы [ 3 ]

24 голосов
/ 08 июля 2014

Начиная с .NET 4.5, для этой цели можно использовать статический метод Task.FromResult<T>():

return Task.FromResult(_Cache[key]);
15 голосов
/ 14 января 2011

Вы можете использовать TaskCompletionSource<TResult>:

var tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(_Cache[key]);
return tcs.Task;

(Обратите внимание, что если _Cache является Dictionary<TKey, TValue>, вы можете использовать TryGetValue, чтобы сделать его одним поиском.)

1 голос
/ 08 июля 2014

Если у вас есть синхронная версия метода, который возвращает результат, вы можете сделать следующее

Task<String>(()=> Hello(Name));

Метод hello будет выглядеть следующим образом.

public String Hello(String Name)
{
   return "Hello " + Name;
}
...