我有一个缓存类,它使用冷(未启动)任务来避免多次运行昂贵的东西。
public class AsyncConcurrentDictionary<TKey, TValue> : System.Collections.Concurrent.ConcurrentDictionary<TKey, Task<TValue>>
{
internal Task<TValue> GetOrAddAsync(TKey key, Task<TValue> 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;
}
}
在您的任务实际使用 C#5 实现之前,这非常有效await
,ala
cache.GetOrAddAsync("key", new Task(async () => {
var r = await AsyncOperation();
return r.FastSynchronousTransform();
}));)`
现在它看起来TaskExtensions.Unwrap()
正是通过Task<Task<T>>
变成 a来完成我所需要的Task<T>
,但它返回的包装器似乎实际上并不支持Start()
- 它引发了一个异常。
TaskCompletionSource
(我为稍微特殊的任务需求而去)似乎也没有任何设施来处理这类事情。
TaskExtensions.Unwrap()
有没有支持“冷任务”的替代方案?