簡體   English   中英

為什么異步運行進程會阻塞線程?

[英]Why does asynchronously running a process block the thread?

基於此答案 ,我具有以下應該異步運行進程的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!");
    }
}

這里可能發生了兩個無關的事情。

首先,至少在Web應用程序的上下文中,異步不會執行您最可能認為的操作。 在動作內部的所有工作完成之前,該動作無法返回響應。 它是異步的事實並不能使其返回更快。 相反,它僅允許將正在運行操作的線程在處於等待狀態時返回到池中。 但是,即使那樣,線程也必須真正處於等待狀態。 運行進程是受CPU限制的,因此此處的異步操作基本上總是同步運行,因為它需要線程來運行進程。

其次,您最有可能在Visual Studio的IIS Express中對此進行測試。 IIS Express是單線程的,因此意味着所有其他請求都將被阻止,直到第一個請求完成。 因此,除非您在完整的IIS(多線程)中運行此請求,否則無論如何都將始終以串行方式處理請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM