Tareas en frío y TaskExtensions.Unwrap

Tengo una clase de almacenamiento en caché que utiliza tareas frías (no iniciadas) para evitar ejecutar lo costoso varias veces.

public class AsyncConcurrentDictionary : System.Collections.Concurrent.ConcurrentDictionary<TKey, Task> { internal Task GetOrAddAsync(TKey key, Task newTask) { var cachedTask = base.GetOrAdd(key, newTask); if (cachedTask == newTask && cachedTask.Status == TaskStatus.Created) // We won! our task is now the cached task, so run it cachedTask.Start(); return cachedTask; } } 

Esto funciona muy bien hasta que su tarea se implementa realmente utilizando la await C # 5, ala

 cache.GetOrAddAsync("key", new Task(async () => { var r = await AsyncOperation(); return r.FastSynchronousTransform(); }));)` 

Ahora parece que TaskExtensions.Unwrap() hace exactamente lo que necesito al convertir la Task<Task> en una Task , pero parece que el contenedor que devuelve no es compatible con Start() . .

TaskCompletionSource (mi destino para necesidades de tareas ligeramente especiales) tampoco parece tener ninguna facilidad para este tipo de cosas.

¿Existe una alternativa a TaskExtensions.Unwrap() que admita “tareas frías”?

Todo lo que necesita hacer es mantener la Task antes de desenvolverla y comenzar con eso:

 public Task GetOrAddAsync(TKey key, Func> taskFunc) { Task> wrappedTask = new Task>(taskFunc); Task unwrappedTask = wrappedTask.Unwrap(); Task cachedTask = base.GetOrAdd(key, unwrappedTask); if (cachedTask == unwrappedTask) wrappedTask.Start(); return cachedTask; } 

Uso:

 cache.GetOrAddAsync( "key", async () => { var r = await AsyncOperation(); return r.FastSynchronousTransform(); });