1

背景情報: 一度に 5 つの同時操作を処理できるシングルトン クラスを作成しようとしています。各操作は で表されSomeAsyncMethodます。


このメソッドは、シングルトン クラス内に存在します。

consumersですConcurrentDictionary<int,Task>

私の問題: 何らかの理由で、ContinueWithデリゲートは の完了前に実行されSomeAsyncMethodます。これが起こっていることを知っている理由は、監視する別のメソッドがあるためですinstance.Consumers.Count-カウントは実行0SomeAsyncMethodです。

何故ですか?

    public bool TryAddDequeueRequest()
    {
        if (instance.Consumers.Count < 5)
        {
            Task bogusTask;
            Task newTask = new Task(SomeAsyncMethod);

            //RUNS AFTER THE REQUEST IS COMPLETED
            newTask.ContinueWith(t =>
            {
                instance.Consumers.TryRemove(t.Id, out bogusTask);
            });

            //WE ADD THE TASK TO QUEUE
            instance.Consumers.TryAdd(newTask.Id, newTask);

            //SET IT AND FORGET IT
            newTask.Start();



            return true;
        }
        else
            return false;
    }
4

2 に答える 2

2

SomeAsyncMethodは、その名前が何らかの指標である場合、非同期メソッドであり、おそらく を返すメソッドTaskです。別のスレッドでこの非同期操作を開始する新しいタスクを作成しています。これは、開始した非同期操作が終了したときではなく、非同期操作の開始Taskが完了したときに返されます。

タスクをアンラップすることもできますが、最初からラップしない方が簡単です。Task非同期メソッドによって返されたの継続を呼び出します。

SomeAsyncMethod().ContinueWith(t =>
{
    instance.Consumers.TryRemove(t.Id, out bogusTask);
});
instance.Consumers.TryAdd(newTask.Id, newTask);

もちろん、一定の並列度でいくつかの非同期操作を実行できるようにしたい場合は、もっと簡単な方法があります。を使用しSemaphoreSlimて、固定された並列度のワーク キューを簡単に作成できます。

public class FixedParallelismQueue
{
    private SemaphoreSlim semaphore;
    public FixedParallelismQueue(int maxDegreesOfParallelism)
    {
        semaphore = new SemaphoreSlim(maxDegreesOfParallelism);
    }

    public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
    {
        await semaphore.WaitAsync();
        try
        {
            return await taskGenerator();
        }
        finally
        {
            semaphore.Release();
        }
    }
    public async Task Enqueue(Func<Task> taskGenerator)
    {
        await semaphore.WaitAsync();
        try
        {
            await taskGenerator();
        }
        finally
        {
            semaphore.Release();
        }
    }
}
于 2014-09-05T20:28:49.030 に答える