围绕现有对象创建任务包装器

时间:2011-01-14 15:56:39

标签: c# task task-parallel-library

我有一个返回Task的方法,其中实现可能需要也可能不需要执行慢速操作以便检索结果。我希望能够简单地将结果值包装到一个任务中,该任务在值已经可用的情况下被标记为已同步完成。今天我有这样的事情:

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 个答案:

答案 0 :(得分:23)

从.NET 4.5开始,您可以将Task.FromResult<T>()静态方法用于此目的:

return Task.FromResult(_Cache[key]);

答案 1 :(得分:15)

您可以使用TaskCompletionSource<TResult>

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

(请注意,如果_CacheDictionary<TKey, TValue>,您可以使用TryGetValue进行单次查询。)

答案 2 :(得分:1)

如果您有返回结果的方法的同步版本,则可以执行以下操作

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

hello方法如下所示。

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