我最近遇到了一个关于异步/等待调用的线程限制示例。在我的电脑上分析和测试代码后,我想出了一种稍微不同的做法。我不确定底层是否基本相同,或者是否有任何值得注意的微妙差别?
以下是基于原始示例的代码:
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创建的任务,因此更加简洁。这个描述准确吗,还是我完全错误?
GetAwaiter()。GetResult()
比Result
更好。但如果可能的话,最好使用await
。 - Stephen Cleary