Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass objects between threads when running a System.Diagnostics process

I won't provide all code, but an example of what I want to do. I have this code for updating GUI elements from an external processes stderr.

I set up my process like this:

ProcessStartInfo info = new ProcessStartInfo(command, arguments);

// Redirect the standard output of the process. 
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.CreateNoWindow = true;

// Set UseShellExecute to false for redirection
info.UseShellExecute = false;

proc = new Process();
proc.StartInfo = info;
proc.EnableRaisingEvents = true;

// Set our event handler to asynchronously read the sort output.
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
proc.Exited += new EventHandler(proc_Exited);

proc.Start();

// Start the asynchronous read of the sort output stream. Note this line!
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();

I then have an event handler

void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
    {
        UpdateTextBox(e.Data);
    }
}

Which invokes the following, which references a specific textbox control.

private void UpdateTextBox(string Text)
{
    if (this.InvokeRequired)
        this.Invoke(new Action<string>(this.SetTextBox), Text);
    else
    {
        textBox1.AppendText(Text);
        textBox1.AppendText(Environment.NewLine);
    }
}

What I want is something like this:

private void UpdateTextBox(string Text, TextBox Target)
{
    if (this.InvokeRequired)
        this.Invoke(new Action<string, TextBox>(this.SetTextBox), Text, Target);
    else
    {
        Target.AppendText(Text);
        Target.AppendText(Environment.NewLine);
    }
}

That I can use to update different Textboxes with from that thread, without having to create a seperate function for every control in the GUI.

Is this possible? (obviously the code above does not work correctly)

Thanks.

UPDATE:

private void UpdateTextBox(string Text, TextBox Target)
{
    if (this.InvokeRequired)
        this.Invoke(new Action<string, TextBox>(this.**UpdateTextBox**), Text, Target);
    else
    {
        Target.AppendText(Text);
        Target.AppendText(Environment.NewLine);
    }
}     

This code does appear to work now as I noticed a typo.. is this ok to use?

like image 920
dave Avatar asked Nov 14 '22 06:11

dave


1 Answers

The code you provided looks good and is good way to send such messages between threads.

like image 156
Pieter van Ginkel Avatar answered Jan 07 '23 16:01

Pieter van Ginkel