2011-01-14 14 views
10

Tengo un método que devuelve una Tarea donde la implementación puede o no necesitar realizar una operación lenta para recuperar el resultado. Me gustaría poder simplemente ajustar el valor del resultado en una Tarea que está marcada como completada sincrónicamente en el caso en que el valor ya esté disponible. Hoy tengo algo como esto:Crear un contenedor de tareas alrededor de un objeto existente

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

es que no hay manera más sencilla de hacer esto que no me requiere para construir la tarea con un delegado cuando ya sé el resultado?

Respuesta

14

Se puede usar un TaskCompletionSource<TResult>:

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

(Tenga en cuenta que si _Cache es una Dictionary<TKey, TValue> podría utilizar TryGetValue para que sea una sola búsqueda.)

1

Si usted tiene una versión sincrónica del método que devuelve el resultado que se puede hacer lo siguiente

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

el método hola vería como a continuación.

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

Comenzando con .NET 4.5, puede utilizar el método estático Task.FromResult<T>() precisamente para este propósito:

return Task.FromResult(_Cache[key]); 
Cuestiones relacionadas