massivemoisture
massivemoisture

Reputation: 87

Why does starting a Process make my C# console app so slow?

I have a C# console application that first initializes some controllers -> start a new process for ADB, forward a port and start an app with it -> then print out a menu that asks user for input:

// Initialize some controllers here
// Create a new process for ADB
...

// --- Start an app with ADB:
var appProcess = new Process();
var appInfo = new ProcessStartInfo();
appInfo.FileName = ADB_PATH;
appInfo.Arguments = ... ; // arguments here
appInfo.RedirectStandardError = true;
appInfo.RedirectStandardOutput = true;
appProcess.StartInfo = appInfo;
appProcess.Start();

appProcess.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e)
{
    // Do something with output data
};
appProcess.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e)
{
   // Do something with eror data
};
appProcess.BeginErrorReadLine();
appProcess.BeginOutputReadLine();
appProcess.Dispose();

// ----------------------------

while (keepAppRunning)
{
    // Print menu
    string userInput = Console.ReadLine()
}

That Console.ReadLine() is so slow. When I press some keys in the console, the keys do not appear right away. Typing has some very noticeable delay. I can't press Enter either. It slows other parts of my app too. I have to wait for like a minute before everything becomes responsive again.

I tried putting that starting app part in isolation and the problem persists so I'm convinced that the problem is somewhere in there.

Upvotes: 0

Views: 425

Answers (1)

Stelio Kontos
Stelio Kontos

Reputation: 520

You're initializing appProcess and appInfo, but then start serverProcess. Was this your intention, or did you mean to call appProcess.Start()?

Also, are you checking if e.Data is null in your callbacks? Those could be the choke point here, but hard to say with the code you've provided. Try putting a breakpoint (or at the very least, a Debug.WriteLine(e.Data.ToString())) in your "do something" code to see how often they're being invoked.

On a side note, I would suggest either putting this in a try/catch/finally (calling appProcess.Dispose() in your finally block), or using the using(...) statement, to ensure that resources are cleaned up if something throws (see the modified version of your code below).

Whatever the case, Console.ReadLine isn't the culprit. It's just where some other problem is manifesting itself (since that's the only user-facing point in the provided code).

using var appProcess = new Process()
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "", // filename here
        Arguments = "", // arguments here
        RedirectStandardError = true,
        RedirectStandardOutput = true
    }
};

appProcess.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
    {
        // Do something with output data, but only if it's not null
    }
};

appProcess.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
    {
        // Do something with eror data, but only if it's not null
    }
};

appProcess.Start();
appProcess.BeginErrorReadLine();
appProcess.BeginOutputReadLine();

while (keepAppRunning)
{
    // Print menu
    string userInput = Console.ReadLine()
}

Upvotes: 1

Related Questions