Creating a task wrapper around an existing object

微笑、不失礼 提交于 2020-12-25 01:40:25

问题


I have a method which returns a Task where the implementation may or may not need to perform a slow operation in order to retrieve the result. I would like to be able to simply wrap the result value into a Task which is marked as having completed synchronously in the case where the value is already available. Today I have something like this:

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

Is there is simpler way to do this that doesn't require me to construct the task with a delegate when I already know the result?


回答1:


You could use a TaskCompletionSource<TResult>:

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

(Note that if _Cache is a Dictionary<TKey, TValue> you could use TryGetValue to make it a single lookup.)




回答2:


Beginning with .NET 4.5, you can use the Task.FromResult<T>() static method for exactly this purpose:

return Task.FromResult(_Cache[key]);



回答3:


If you have a synchronous version of the method that returns the result you can do the following

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

The hello method would look like below.

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


来源:https://stackoverflow.com/questions/4692963/creating-a-task-wrapper-around-an-existing-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!