13

私は最近、async/await 呼び出しのスレッドを調整する例に出くわしました。自分のマシンでコードを分析して遊んだ後、同じことを行う少し異なる方法を思いつきました。私が確信していないのは、ボンネットの下で起こっていることはほとんど同じなのか、それとも注目に値する微妙な違いがあるのか​​ということです。

元の例に基づくコードは次のとおりです。

private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5);

public async Task CallThrottledTasks()
{
    var tasks = new List<Task>();

    for (int count = 1; count <= 20; count++)
    {
        await _semaphore.WaitAsync();

        tasks.Add(Task.Run(async () =>
            {
                try
                {
                    int result = await LongRunningTask();
                    Debug.Print(result.ToString());
                }
                finally
                {
                    _semaphore.Release();
                }
            }));
    }

    await Task.WhenAll(tasks);

    Debug.Print("Finished CallThrottledTasks");
}

そして、これが同じコードに対する私の見解です:

private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5);

public async Task CallThrottledTasks()
{
    var tasks = new List<Task>();

    for (int count = 1; count <= 20; count++)
    {
        await _semaphore.WaitAsync();

        tasks.Add(LongRunningTask().ContinueWith(t =>
        {
            try
            {
                int result = t.Result;
                Debug.Print(result.ToString());
            }
            finally
            {
                _semaphore.Release();
            }
        }));
    }

    await Task.WhenAll(tasks);

    Debug.Print("Finished CallThrottledTasks");
}

私はおそらくかなり離れていますが、Task.RunアプローチはLongRunningTask()を実行するタスクを作成し、結果を出力するために継続を追加しているようですが、私のアプローチはTask.Runによって作成されたタスクをバイパスし、少し無駄がありません結果として。これは正確ですか、それとも私はここでベースから外れていますか?

4

1 に答える 1