Can you access UI elements from another thread? (get not set)

Edit: It seems I have to take back what I wrote before. Tried the following:

Added a textbox called myTextBox and tried to retrieve the value of the Text property:

Thread t = new Thread(
    o =>
    {
        Thread.Sleep(2000);                    
        string value = myTextBox.Text;
        Thread.Sleep(2000);
    });
t.Start();

And it seems that the app (WPF) crashes after 2 seconds. Using the dispatcher works:

Thread t = new Thread(
    o =>
    {
        Thread.Sleep(2000);
        myTextBox.Dispatcher.BeginInvoke(
            (Action)(() => { string value = myTextBox.Text; }));
        Thread.Sleep(2000);
    });
t.Start();

Thus, you still need to go through the dispatcher thread when reading values from GUI components, at least in WPF.

Second edit: This gets better. Apparently repeating the experiment for classic WinForms reveals that it works to read the Text property without using Invoke/BeginInvoke. Interestingly enough, it seems that also setting the property works fine (without invoke), although I’ll wager it’s not thread safe and the app doesn’t complain for some reason.

Bottom line: It’s a good idea in any case to use the dispatcher when interacting with GUI components from other threads, as it ensures the reads/writes are serialized to a single thread and so you have no thread-safety issues.

Leave a Comment