2011-12-20 13 views
12

Tengo una clase encargada de recuperar recursos que también los almacena en caché para un acceso rápido. La clase expone un método asíncrono para la recuperación de un recurso:Cómo ejecutar un código de forma asincrónica usando las tareas

public Task<object> GetResourceAsync(string resourceName) 
{ 
    return Task.Factory.StartNew<object>(() => 
    { 
     // look in cache 

     // if not found, get from disk 

     // return resource 
    }); 
} 

código continuación, el cliente tiene el siguiente aspecto:

myResourceProvider.GetResourceAsync("myResource") 
    .ContinueWith<object>(t => Console.WriteLine("Got resource " + t.Result.ToString())); 

De esta manera, un subproceso de fondo se utiliza siempre. Sin embargo, no deseo que el código se ejecute de forma asíncrona si el objeto se encontró en la memoria caché. Si se encontró en el caché, me gustaría devolver el recurso de inmediato y no tener que usar otro hilo.

Gracias.

Respuesta

19

.NET 4.5 tiene Task.FromResult que le permite devolver un Task<T>, pero en lugar de ejecutar un delegado en un subproceso de subprocesamiento, establece explícitamente el valor de retorno de la tarea.

Así, en el contexto de su código:

public Task<object> AsyncGetResource(string resourceName) 
{ 
    object valueFromCache; 
    if (_myCache.TryGetValue(resourceName, out valueFromCache)) { 
     return Task.FromResult(valueFromCache); 
    } 
    return Task.Factory.StartNew<object>(() => 
    { 
     // get from disk 
     // add to cache 
     // return resource 
    }); 
} 

Si todavía estás en .NET 4.0, puede utilizar TaskCompletionSource<T> a hacer lo mismo:

var tcs = new TaskCompletionSource<object>(); 
tcs.SetResult(...item from cache...); 
return tcs.Task; 
+0

Esto es exactamente lo que yo estaba buscando. ¡Gracias! –

+0

+1 Estaba haciendo esta pregunta (http://stackoverflow.com/questions/15316613/real-life-scenarios-for-using-taskcompletionsourcet) y ahora puedo ver cuándo debería usarla. –

+0

@joe ¿puede mejorar este código (agregue una solución) para Task.FromResult? –

Cuestiones relacionadas