Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it

In my Windows I have a TextBox which I like to update (text property) from another thread. When doing so, I get the InvalidOperationException (see title). I have found different links in google explaining this, but I still can't seem to make it work.

What I've tried is this:

Window1 code:

private static Window1 _myWindow;
private MessageQueueTemplate _messageQueueTemplate;
private const string LocalTemplateName = "LocalExamSessionAccessCodeMessageQueueTemplate";
private const string RemoteTemplateName = "RemoteExamSessionAccessCodeMessageQueueTemplate";

...
public Window1()
{
    InitializeComponent();
    _myWindow = this;
}

public static Window1 MyWindow
{
    get
    {
        return _myWindow;
    }
}

public void LogText(string text)
{
    informationTextBox.Text += text + Environment.NewLine;
}
...

In another class (actually a spring.NET Listener adapter, listening to a certain queue, started in another thread).

var thread = new Thread(
    new ThreadStart(
        delegate()
            {
                Window1.MyWindow.Dispatcher.Invoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new Action(
                        delegate()
                            {
                                Window1.MyWindow.LogText(text);
                            }
                        ));
            }
        ));

It doesn't throw an error, but the text in the LogText method in Window1 isn't triggered, so the text isn't updated.

So basically, I want to update this TextBox component from another class running in another thread.

like image 811
Lieven Cardoen Avatar asked Aug 16 '10 09:08

Lieven Cardoen


2 Answers

Window1.MyWindow.informationTextBox.Dispatcher.Invoke(
    DispatcherPriority.Normal,
    new Action(() => Window1.MyWindow.informationTextBox.Text += value));
like image 126
Lieven Cardoen Avatar answered Nov 12 '22 15:11

Lieven Cardoen


Well, using Dispatcher.Invoke or BeginInvoke is definitely the way to go, but you haven't really shown much code other than creating a thread - for example, you haven't started the thread in your second code block.

If you put the Dispatcher.Invoke code in the place where previously you were getting an InvalidOperationException, it should be fine.

like image 29
Jon Skeet Avatar answered Nov 12 '22 16:11

Jon Skeet