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

Sta*_*ar 15 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());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我已经知道结果时,是否有更简单的方法来执行此操作并不需要我使用委托构造任务?

Mat*_*ard 29

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

return Task.FromResult(_Cache[key]);
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 16

你可以使用TaskCompletionSource<TResult>:

var tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(_Cache[key]);
return tcs.Task;
Run Code Online (Sandbox Code Playgroud)

(注意,如果_Cache是,Dictionary<TKey, TValue>您可以使用TryGetValue它来进行单个查找.)