Ниже приведен упрощенный вариант кода, с которым я столкнулся. Когда я запускаю его в консольном приложении, он работает так, как ожидалось. Все запросы выполняются параллельно, а Task.WaitAll()
возвращается, когда все они завершены.
Однако, когда этот код работает в веб-приложении, запрос просто зависает. Когда я присоединяю отладчик и разбиваю все, он показывает, что выполнение выполняется на Task.WaitAll()
. И первая задача завершена, но другие никогда не заканчиваются.
Я не могу понять, почему он зависает при работе в ASP.NET, но отлично работает в консольном приложении.
public Foo[] DoWork(int[] values)
{
int count = values.Length;
Task[] tasks = new Task[count];
for (int i = 0; i < count; i++)
{
tasks[i] = GetFooAsync(values[i]);
}
try
{
Task.WaitAll(tasks);
}
catch (AggregateException)
{
// Handle exceptions
}
return ...
}
public async Task<Foo> GetFooAsync(int value)
{
Foo foo = null;
Func<Foo, Task> executeCommand = async (command) =>
{
foo = new Foo();
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
ReadFoo(reader, foo);
}
};
await QueryAsync(executeCommand, value);
return foo;
}
public async Task QueryAsync(Func<SqlCommand, Task> executeCommand, int value)
{
using (SqlConnection connection = new SqlConnection(...))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
// Set up query...
await executeCommand(command);
// Log results...
return;
}
}
}