Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# GUI Application, Another class from another thread updating the UI

I've been researching on how to do this for about a week and I'm still not sure about the correct approach, in some examples I see the Thread class is used in others I see Invoke is used which has confused me a bid.

I have a GUI program in c# which contains a textBox which will be used to give information to the user.

The problem I'm facing is that I'm not sure how I can append text to textBox from another class which is running on another thread. If someone can show me a working example, it would help me greatly.

Best Regards!

like image 793
Arya Avatar asked Feb 26 '23 23:02

Arya


1 Answers

Easy:

MainWindow.myInstance.Dispatcher.BeginInvoke(new Action(delegate() {MainWindow.myInstance.myTextBox.Text = "some text";});

WHERE MainWindow.myInstance is a public static variable set to the an instance of MainWindow (should be set in the constructor and will be null until an instance is constructed).

Ok thats a lot in one line let me go over it:

When you want to update a UI control you, as you say, have to do it from the UI thread. There is built in way to pass a delegate (a method) to the UI thread: the Dispatcher. I used MainWindow.myInstance which (as all UI components) contains reference to the Dispatcher - you could alternatively save a reference to the Dispatcher in your own variable:

Dispatcher uiDispatcher = MainWindow.myInstance.Dispatcher;

Once you have the Dispatcher you can either Invoke() of BeginInvoke() passing a delegate to be run on the UI thread. The only difference is Invoke() will only return once the delegate has been run (i.e. in your case the TextBox's Text has been set) whereas BeginInvoke() will return immediately so your other thread you are calling from can continue (the Dispatcher will run your delegate soon as it can which will probably be straight away anyway).

I passed an anonymous delegate above:

delegate() {myTextBox.Text = "some text";}

The bit between the {} is the method block. This is called anonymous because only one is created and it doesnt have a name - but I could instantiated a delegate:

Action myDelegate = new Action(UpdateTextMethod);

void UpdateTextMethod() 
{
    myTextBox.Text = "new text";
}

Then passed that:

uiDispatcher.Invoke(myDelegate);

I also used the Action class which is a built in delegate but you could have created your own - you can read up more about delegates on MSDN as this is going a bit off topic..

like image 110
markmnl Avatar answered Feb 28 '23 12:02

markmnl