WiXXeY
WiXXeY

Reputation: 1001

Reading Console of another exe in C# hangs UI

I am reading line by line Console of another exe in my C# project, the project successfully reads each of console line but the problem i am facing is when the exe start execution my c# form hangs and it waits till the external exe is not fully executed.

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = EXELOCATION;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = argv;
startInfo.RedirectStandardOutput = true;
try
{
    // Start the process with the info we specified.
    // Call WaitForExit and then the using statement will close.
    using (exeProcess = Process.Start(startInfo))
    {
        using (StreamReader reader = exeProcess.StandardOutput)
        {
            string result;
            while ((result = reader.ReadLine() ) != null)
            {                            
                scanning.Text = result;
                scanning.Refresh();
                Console.Write(result);
            }
        }

    }

how should i tackle this problem, kindly guide me

Upvotes: 1

Views: 263

Answers (4)

Benoit Blanchon
Benoit Blanchon

Reputation: 14571

You can use Process.OutputDataReceived (MSDN)

It allows to attach an event handler that will be called whenever data is available.

using (exeProcess = Process.Start(startInfo))
{
    exeProcess.OutputDataReceived +=
        (sender, args) =>
            {
                scanning.Text = args.Data;
                scanning.Refresh();
                Console.Write(args.Data);
            };

    exeProcess.BeginOutputReadLine();

    // do whatever you want here

    exeProcess.WaitForExit();
}

Anyway, if you do that in the UI thread it will still block the UI.

Plus, if you want to update the content of a UI control from another thread, you should call BeginInvoke().

In that case, BackgroundWorker is a good help. It will create the background thread for you; and you can safely update the UI in the ProgressChanged event handler.

Upvotes: 2

jiten
jiten

Reputation: 5264

You should use BackgroundWorker.

Using BackgroundWorker:

Here are the minimum steps in using BackgroundWorker:

  • Instantiate BackgroundWorker and handle the DoWork event.
  • Call RunWorkerAsync, optionally with an object argument.

This then sets it in motion. Any argument passed to RunWorkerAsync will be forwarded to DoWork’s event handler, via the event argument’s Argument property. Here’s an example:

class Program
{
  static BackgroundWorker _bw = new BackgroundWorker();

  static void Main()
  {
    _bw.DoWork += bw_DoWork;
    _bw.RunWorkerAsync ("Message to worker");
    Console.ReadLine();
  }

  static void bw_DoWork (object sender, DoWorkEventArgs e)
  {
    // This is called on the worker thread
    Console.WriteLine (e.Argument);        // writes "Message to worker"
    // Perform time-consuming task...
  }
}

Upvotes: 1

Alex
Alex

Reputation: 2811

If you're doing everything in a single blocking thread then your application will have to wait until the other exe has returned control to your form.

The solution is to do the reading in a separate thread, which will pass the information back to your application as it becomes available. This is slightly more complex but it's not too difficult to do - you should read about the threading classes available, such as Background Worker.

Upvotes: 0

Daniel Casserly
Daniel Casserly

Reputation: 3480

I would suggest learning about threading. The best and easiest way to get started is the Background Worker class in Winforms.

But you should check out the System.Threading namespace too.

Upvotes: 0

Related Questions