Reputation: 1001
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
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
Reputation: 5264
You should use BackgroundWorker.
Using BackgroundWorker:
Here are the minimum steps in using BackgroundWorker:
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
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
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