高価なものを複数回実行することを避けるために、コールド (開始されていない) タスクを使用するキャッシュ クラスがあります。
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;
}
}
await
これは、C#5 のalaを使用してタスクが実際に実装されるまで、うまく機能します。
cache.GetOrAddAsync("key", new Task(async () => {
var r = await AsyncOperation();
return r.FastSynchronousTransform();
}));)`
に変換するTaskExtensions.Unwrap()
ことで必要なことを正確に実行しているように見えますが、返されるラッパーは実際にはサポートされていないようです-例外がスローされます。Task<Task<T>>
Task<T>
Start()
TaskCompletionSource
(少し特別なタスクのニーズに対応するために私が行く)には、この種の機能もないようです。
TaskExtensions.Unwrap()
「コールドタスク」をサポートする代替手段はありますか?