私は最近、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によって作成されたタスクをバイパスし、少し無駄がありません結果として。これは正確ですか、それとも私はここでベースから外れていますか?