以下是我遇到问题的代码的简化版本。当我在控制台应用程序中运行此代码时,它按预期工作。所有查询并行运行,Task.WaitAll()
在它们全部完成后返回。
然而,当此代码在 Web 应用程序中运行时,请求会一直挂起。当我附加调试器并断开所有连接时,它显示执行正在等待 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;
}
}
}
await
后会返回到相同的上下文,但可能在不同的线程上执行。因此,我认为你不能真正称其为“该请求的主线程”,因为该线程在请求的生命周期内可能会发生变化。 - svick