Я хочу несколько раз вызвать асинхронный метод в тесте xUnit и дождаться завершения всех вызовов, прежде чем продолжить выполнение.Я прочитал, что могу использовать Task.WhenAll()
и Task.WaitAll()
именно для этого сценария.Однако по какой-то причине код блокируется.
[Fact]
public async Task GetLdapEntries_ReturnsLdapEntries()
{
var ldapEntries = _fixture.CreateMany<LdapEntryDto>(2).ToList();
var creationTasks = new List<Task>();
foreach (var led in ldapEntries)
{
var task = _attributesServiceClient.CreateLdapEntry(led);
task.Start();
creationTasks.Add(task);
}
Task.WaitAll(creationTasks.ToArray()); //<-- deadlock(?) here
//await Task.WhenAll(creationTasks);
var result = await _ldapAccess.GetLdapEntries();
result.Should().BeEquivalentTo(ldapEntries);
}
public async Task<LdapEntryDto> CreateLdapEntry(LdapEntryDto ldapEntryDto)
{
using (var creationResponse = await _httpClient.PostAsJsonAsync<LdapEntryDto>("", ldapEntryDto))
{
if (creationResponse.StatusCode == HttpStatusCode.Created)
{
return await creationResponse.Content.ReadAsAsync<LdapEntryDto>();
}
throw await buildException(creationResponse);
}
}
Тестируемая система представляет собой оболочку вокруг HttpClient
, вызывающего веб-службу, await
s ответ и, возможно, await
s.чтение содержимого ответа, которое, наконец, десериализовано и возвращено.
Когда я заменяю часть foreach
в тесте следующим (то есть, не использую Task.WhenAll() / WaitAll()
), код выполняется без тупика:
foreach (var led in ldapEntries)
{
await _attributesServiceClient.CreateLdapEntry(led);
}
Что именно происходит?
РЕДАКТИРОВАТЬ: Хотя этот вопрос был отмечен как дубликат, я не вижу, как связанный вопрос связан с этим.Все примеры кода в ссылке используют .Result
, который, насколько я понимаю, блокирует выполнение до завершения задачи.Напротив, Task.WhenAll()
возвращает задачу, которую можно ожидать и которая заканчивается, когда все задачи завершены.Так почему же ожидается Task.WhenAll()
взаимоблокировка?