Jared
Jared

Reputation: 2133

Thread Cannot Access Object

I have a UserControl that is added to my Main window. The Main code continuously receives TCP messages and interacts with the UserControl accordingly. One of the UserControl's methods that is called by Main is AddMessage:

internal void AddMessage(Paragraph p)
{
    if (txtViewer.Dispatcher.CheckAccess())
    {
        txtViewer.Document.Blocks.Add(p);
    }
    else
    {
        Dispatcher.Invoke(new Action(() =>
            {
                txtViewer.Document.Blocks.Add(p);
            }
        ));
    }
}

The line within Dispatcher.Invoke always throws an InvalidOperationException. I've looked around at similar issues, and most of them were cases where the Dispatcher wasn't being used, so I don't know why my code isn't working. I suppose I'm using it incorrectly, or it may have something to do with the Paragraph object being passed between threads.

Thanks, Jared

Upvotes: 3

Views: 574

Answers (3)

paparazzo
paparazzo

Reputation: 45096

I had a similar problem in could not bind a DocumentViewer asynch as FlowDocument derived from Dispatcher. The UI cannot bind to an object that derives from Dispatcher on another thead. I had to serialize the FlowDocument to string (does not derive from dispatcher) using XamlWriter.Save then de-serialize in a Converter.

Upvotes: 1

brunnerh
brunnerh

Reputation: 184296

You check the access on the Dispatcher of the txtViewer but invoke on some other Dispatcher if CheckAccess fails, you know nothing about said Dispatcher. You want to invoke on the txtViewer.Dispatcher instead.

Upvotes: 1

Jon Raynor
Jon Raynor

Reputation: 3892

It might have something to do with the object being frozen.

The idea of an object deriving from Freezable is that it normally is in a read/write state, but can be explicitly put into a read-only state using the Freeze method. A frozen object can be used more efficiently in WPF because it doesn’t need to notify consumers of the object that its value has changed.

Graphical objects in WPF like brushes and 3D geometries derive from Freezable. Initially unfrozen, a change to one of these objects results in consumers of the objects being notified of the change.

If you have an object deriving from Freezable that you don’t plan to change, you can make the object read-only using the Freeze method.

After freezing the object, if you try modifying it, you’ll get an InvalidOperationException. But WPF will be more efficient in its use of the object.

Taken From Here:

http://wpf.2000things.com/tag/freezable/

Upvotes: 0

Related Questions