基于this answer,我有以下ASP.NET Action,它应该异步运行一个进程。但是,当我发出多个并行请求时,每个请求只在前一个请求完成后运行。为什么会这样?
public async Task<ActionResult> Index(string url)
{
var exePath = Server.MapPath("~/App_Data/dummy/bin/dummy.exe");
var startInfo = new ProcessStartInfo
{
FileName = exePath,
Arguments = url,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
var process = new Process{ EnableRaisingEvents = true, StartInfo = startInfo};
var tcs = new TaskCompletionSource<Process>();
process.Exited += (sender, a) =>
{
tcs.SetResult(process);
};
process.Start();
await tcs.Task;
// todo: return process status/output
return View();
}
MVC Action中调用的进程dummy.exe
的代码是:
class Program
{
static void Main(string[] args)
{
Thread.Sleep(5000);
Console.WriteLine("Hello world!");
}
}
答案 0 :(得分:1)
这里可能发生了两件无关的事情。
首先,async不会做你最有可能想到的事情,至少在Web应用程序的上下文中是这样。在操作内的所有工作完成之前,操作无法返回响应。它是异步的事实并没有让它更快地返回。相反,它只允许运行操作的线程在处于等待状态时返回到池中。然而,即使这样,线程也必须真正等待。运行进程是受CPU限制的,因此这里的异步操作基本上会同步运行,因为它需要线程来运行该进程。
其次,您最有可能在Visual Studio中的IIS Express中对此进行测试。 IIS Express是单线程的,因此意味着所有进一步的请求将被阻止,直到第一次完成。因此,除非您在完整的IIS(多线程)中运行此命令,否则将始终以串行方式处理请求。