0

Based on this answer, I have the following ASP.NET Action that's supposed to run a process asynchronously. However, when I make multiple parallel requests, each runs only after the previous one completes. Why does this happen?

    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();
    }

The code for dummy.exe, the process called in the MVC Action, is:

class Program
{
    static void Main(string[] args)
    {
        Thread.Sleep(5000);
        Console.WriteLine("Hello world!");
    }
}
Community
  • 1
  • 1
makhdumi
  • 1,308
  • 11
  • 35
  • 2
    Random guess - session state locking? – Alexei Levenkov Jun 13 '16 at 16:19
  • @RenéVogt: The `Main` method here is part of the program the method above it calls, not the other way around. The method here is an MVC action, so it's being called as part of the request-pipeline. – Chris Pratt Jun 13 '16 at 16:20
  • @ChrisPratt thx, my bad... – René Vogt Jun 13 '16 at 16:22
  • @AlexeiLevenkov thanks, I hadn't heard of it before. Checking that out now. Edit: nope, nevermind, this is a bare bones MVC application (Empty template) with no Session store :( – makhdumi Jun 13 '16 at 16:25
  • @AlexeiLevenkov that was actually the cause, sort of, thank you! The "session-state locking" was in Chrome. It was pending requests to the same URL. So it was just my browser. – makhdumi Jun 13 '16 at 16:37
  • 1
    @Al-Muhandis I meant ASP.Net session state locking (see http://stackoverflow.com/questions/3629709/i-just-discovered-why-all-asp-net-websites-are-slow-and-i-am-trying-to-work-out), but I'm glad it gave you good hint to find a problem. – Alexei Levenkov Jun 13 '16 at 16:42

1 Answers1

1

There's probably two unrelated things going on here.

First, async doesn't do what you most likely think it does, at least in the context of a web application. The action cannot return a response until all work inside the action is complete. The fact that it's async doesn't make it return faster. Rather, it merely allows the the thread that is running the action to be returned to the pool while it's in a wait-state. However, even then, the thread must be truly waiting. Running a process is CPU-bound, so your async action here will essentially run synchronously always, because it needs the thread to run the process.

Second, you're most likely testing this in IIS Express, within Visual Studio. IIS Express is single-threaded, so that means all further requests will be blocked until the first completes. Therefore, unless you're running this in full IIS (which is multi-threaded) the requests will always be handled serially, regardless.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • I tested in IIS. Could you elaborate on how running the process is CPU bound? Isn't that only the case if I call `WaitForExit()`? – makhdumi Jun 13 '16 at 16:29