4

高価なものを複数回実行することを避けるために、コールド (開始されていない) タスクを使用するキャッシュ クラスがあります。

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()「コールドタスク」をサポートする代替手段はありますか?

4

1 に答える 1