Thread Cannot Access Object - c#

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

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.

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.

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/

Related

Getting exception when using high-resolution timer to work in WPF [duplicate]

A common exception one can get when working with multiple threads in WPF is:
The calling thread cannot access this object because a different thread owns it
What are the options to deal with this properly?
Depending on the situation there are various options:
Accessing a control from another thread
e.g. updating a TextBlock with progress information.
Data Binding:
In this case the easiest thing you can do is avoiding the direct interaction with the control. You can just bind the property you want to access or modify to an object whose class implements INotifyPropertyChanged and then set the property on that object instead. The framework will handle the rest for you. (In general you rarely should need to interact with UI-elements directly, you can almost always bind the respective properties and work with the binding source instead; one case where direct control access may be necessary is control authoring.)
There are some cases where data binding alone is not enough, for example when trying to modify a bound ObservableCollection<T>, for this you need...
Dispatching:
You can dispatch your accessing code to the thread owning the object, this can be done by calling Invoke or BeginInvoke on the Dispatcher owning the object being accessed (getting this Dispatcher is possible on another thread).
e.g.
new Thread(ThisThreadStart).Start();
void ThisThreadStart()
{
textBlock.Dispatcher.Invoke(new Action(() => textBlock.Text = "Test"));
}
If it is not clear on which thread a method is executed you can use Dispatcher.CheckAccess to either dispatch or execute an action directly.
e.g.
void Update()
{
Action action = () => myTextBlock.Text = "Test";
var dispatcher = myTextBlock.Dispatcher;
if (dispatcher.CheckAccess())
action();
else
dispatcher.Invoke(action);
}
If an object is not a DispatcherObject and you still need the associated Dispatcher you can use Dispatcher.CurrentDispatcher in the thread creating the object (so doing this in the method being executed by a thread will not do you any good). For convenience as you usually create objects on the application's main UI thread; you can get that thread's Dispatcher from anywhere using Application.Current.Dispatcher.
Special cases:
BackgroundWorker
Move any control access to ProgressChanged as it occurs on the thread that created the instance (which should of course be the UI-thread)
Timers
In WPF you can use the DispatcherTimer for convenience, it does the dispatching for you so any code in Tick is invoked on the associated dispatcher. If you can delegate the dispatching to the data binding system you of course can use a normal timer as well.
You can read more about how the Dispatcher queue works and WPF threading in general on MSDN.
Accessing an object created on another thread
e.g. loading an image in the background.
If the object in question is not Freezable you should in general simply avoid creating it on another thread or restricting access to the creating thread. If it is Freezable you just need to call Freeze to make it accessible to other threads.
Accessing a data object from another thread
That is, the type whose instance is being updated is user-code. If an exception is thrown this situation probably came about by someone using DependencyObject as base type for a data class.
This situation is the same as accessing a control and the same approaches can be applied but usually it should be avoided in the first place. Granted, this allows for simple property change notifications via dependency properties and those properties can also be bound but often enough this is just not worth giving up thread-independency. You can get change notifications from INotifyPropertyChanged and the binding system in WPF is inherently asymmetrical, there always is a property that is bound (target) and something that is the source for this binding. Usually the UI is the target and the data is the source, meaning that only UI components should need dependency properties.
That would be several hundred lines of code, for something I "figured out".
But the summary is:
App_OnStartup
generate a background thread
in the callback,
Call
Application.Current.MainWindow.Dispatcher.CheckAccess() - gets the exception
Application.Current.Dispatcher.CheckAccess() does not
I have a udp listener object that communicates through events where the method/callbacks are +='ed in my mainWindow wpf .cs file.
The event handler functions are called with parameters, one being the message I want displayed in a listbox in the mainWindow.cs
Using the information in this thread by H.B. above;
I have added, tested and handled the crossthread in wpf in my eventhandler callback using the following code, but I use a real message not a hard coded one:
listBox1.Dispatcher.Invoke(new Action(() => listBox1.Items.Add("MessageHere")));
UPDATE:
This is better because you can put more things in the anonymous function.
listBox1.Dispatcher.Invoke((Action)delegate
{
listBox1.Items.Add(e.ReaderMessage);
});

Can't Access Variable Because It Is Owned By Another Thread [duplicate]

A common exception one can get when working with multiple threads in WPF is:
The calling thread cannot access this object because a different thread owns it
What are the options to deal with this properly?
Depending on the situation there are various options:
Accessing a control from another thread
e.g. updating a TextBlock with progress information.
Data Binding:
In this case the easiest thing you can do is avoiding the direct interaction with the control. You can just bind the property you want to access or modify to an object whose class implements INotifyPropertyChanged and then set the property on that object instead. The framework will handle the rest for you. (In general you rarely should need to interact with UI-elements directly, you can almost always bind the respective properties and work with the binding source instead; one case where direct control access may be necessary is control authoring.)
There are some cases where data binding alone is not enough, for example when trying to modify a bound ObservableCollection<T>, for this you need...
Dispatching:
You can dispatch your accessing code to the thread owning the object, this can be done by calling Invoke or BeginInvoke on the Dispatcher owning the object being accessed (getting this Dispatcher is possible on another thread).
e.g.
new Thread(ThisThreadStart).Start();
void ThisThreadStart()
{
textBlock.Dispatcher.Invoke(new Action(() => textBlock.Text = "Test"));
}
If it is not clear on which thread a method is executed you can use Dispatcher.CheckAccess to either dispatch or execute an action directly.
e.g.
void Update()
{
Action action = () => myTextBlock.Text = "Test";
var dispatcher = myTextBlock.Dispatcher;
if (dispatcher.CheckAccess())
action();
else
dispatcher.Invoke(action);
}
If an object is not a DispatcherObject and you still need the associated Dispatcher you can use Dispatcher.CurrentDispatcher in the thread creating the object (so doing this in the method being executed by a thread will not do you any good). For convenience as you usually create objects on the application's main UI thread; you can get that thread's Dispatcher from anywhere using Application.Current.Dispatcher.
Special cases:
BackgroundWorker
Move any control access to ProgressChanged as it occurs on the thread that created the instance (which should of course be the UI-thread)
Timers
In WPF you can use the DispatcherTimer for convenience, it does the dispatching for you so any code in Tick is invoked on the associated dispatcher. If you can delegate the dispatching to the data binding system you of course can use a normal timer as well.
You can read more about how the Dispatcher queue works and WPF threading in general on MSDN.
Accessing an object created on another thread
e.g. loading an image in the background.
If the object in question is not Freezable you should in general simply avoid creating it on another thread or restricting access to the creating thread. If it is Freezable you just need to call Freeze to make it accessible to other threads.
Accessing a data object from another thread
That is, the type whose instance is being updated is user-code. If an exception is thrown this situation probably came about by someone using DependencyObject as base type for a data class.
This situation is the same as accessing a control and the same approaches can be applied but usually it should be avoided in the first place. Granted, this allows for simple property change notifications via dependency properties and those properties can also be bound but often enough this is just not worth giving up thread-independency. You can get change notifications from INotifyPropertyChanged and the binding system in WPF is inherently asymmetrical, there always is a property that is bound (target) and something that is the source for this binding. Usually the UI is the target and the data is the source, meaning that only UI components should need dependency properties.
That would be several hundred lines of code, for something I "figured out".
But the summary is:
App_OnStartup
generate a background thread
in the callback,
Call
Application.Current.MainWindow.Dispatcher.CheckAccess() - gets the exception
Application.Current.Dispatcher.CheckAccess() does not
I have a udp listener object that communicates through events where the method/callbacks are +='ed in my mainWindow wpf .cs file.
The event handler functions are called with parameters, one being the message I want displayed in a listbox in the mainWindow.cs
Using the information in this thread by H.B. above;
I have added, tested and handled the crossthread in wpf in my eventhandler callback using the following code, but I use a real message not a hard coded one:
listBox1.Dispatcher.Invoke(new Action(() => listBox1.Items.Add("MessageHere")));
UPDATE:
This is better because you can put more things in the anonymous function.
listBox1.Dispatcher.Invoke((Action)delegate
{
listBox1.Items.Add(e.ReaderMessage);
});

BindingOperations.EnableCollectionSynchronization mystery in WPF

I have been struggling to grasp this concept and even after many experiments I still can't figure out what the best practise is with ObservableCollections in WPF and using BindingOperations.EnableCollectionSynchronization.
If I have a viewmodel with an observable collection and I enable collection sync on it using a lock as shown below:
m_obsverableCollection = new ObservableCollection<..>;
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection,
m_obsverableCollectionLock);
Does that mean that every modification and enumeration over that observable collection will:
Lock the collection automatically using the m_obsverableCollectionLock?
Marshall all modifications on the thread on which the collection was created?
Marshall all modifications on the thread on which the binding operations call was made?
When using BindingOperations.EnableCollectionSynchronization, will I ever need to do any kind of locking explicitly?
The problem which spawned all this is that even after using BindingOperations.EnableCollectionSynchronization and locking items using the same lock I passed into that method, very occasionally I get the "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread." exception
We finally got to the bottom of it:
We have to enable CollectionSynchronization on the dispatcher:
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
BindingOperations.EnableCollectionSynchronization(m_obsverableCollection, m_observableCollectionLock);
}));
Then everytime any other thread wants to access the observable you can simply:
lock (m_observableCollectionLock)
m_observableCollection.Add(...)
I haven't used that particular syntax, but whenever I need to update an ObservableCollection from a background thread, I follow this pattern:
// i just typed this off the top of my head, so be forewarned... :)
lock(someLockingObj)
{
Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
... update here....
}));
}
Usually the error that you've encountered occurs when a bg thread is trying to update the ObservableCollection directly, without the Dispatcher.BeginInvoke (or even Invoke would work too, most of the times, IMHO).

MultiThreading COMObject and UI Thread (C#)

This is my first post here as actually i usually solve all my issue with the awesome
post database you can find here. But I'm actually stuck right now:
I'm working on a project following the MVVM including a COM object.
As I read during my research, I understand that the COM object is only accessible from the thread which created it. My COM object implements the following interface
interface IComUpdate
{
void Update();
}
So when I create my COM object, each time there is an update (I dont know when, its random) the COM Server will call the Update() of the COM object class I did implement.
My goal was to create a different thread, naming a COM object thread, where the COM object exist independantly of my UI Thread, so everytime there is an update, I handle it in a different thread than the UI Thread.
Actually it is working:
At the Beginning of my ViewModel I create a collection of a specific object.
This object, lets call it ModelObj, is part of the model and defines a static constructor in which the application, apart from initializing some variables, creates and starts a new thread for the COM object:
Thread t = new System.Threading.Thread(() =>
{
System.Threading.Thread.CurrentThread.Name = "Thread of COM Object";
IComUpdate myComObj;
myComObj = (IComUpdate)Activator.CreateInstance(blabla);
Application.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
It actually works very well, in the Update() implementation of my COM object, I actually see that the thread is the one just created and not the UI thread.
Now the issue is this: this ModelObj I create implements the INotifyPropertyChanged interface.
My thinking was the following: each time the COM object receives an update, I handle data from the COM object thread, and update some property of my ModelObjinstance from this thread, so these properties will then raise the property change of my ModelObj and the UI thread will update the User Interface.
If the UI update takes too much time, I might miss some Update() to appear on the screen but the COM object will have them recorded in my ModelObj instance so it is not very important that the UI catch all the updates, I just didnt want the COM object to have to wait for the UI to be updated to be called again.
I read tons of posts and thought then that my RaisePropertyChanged("property") would fail.
Actually even in the COM object's thread, the RaisePropertyChanged successfully executes, so tracing my code, I see it switches to my ViewModel assembly where I do
// Here I'm still in the thread of my COM object!
base.NotifyOfPropertyChange<string>(() => this.property)
and then the UI Update.
Note: I'm using Caliburn Micro for binding between my View in WPF and my ViewModel.
So I can't trace after this base.NotifyOfPropertyChange<string>(() => this.property). Maybe Caliburn handles the thread switch, this is not really my issue.
What I can say is that my COM object thread waits for the UI to update to get to the next instruction after my RaisePropertyChanged("property"), so it's exactly the same as if the UI thread did the whole work.
I want my COM object thread to update my ModelObj which will send to send the UI a message to update (because some fields of this ModelObj have changed) and continue immediatly, without knowing if the UI actually updates or not.
Does someone got an idea about this behaviour?
Thank you very much.
####UPDATE####
Thanks everyone for such quick answers.
I did actually as Zdeslav Vojkovic suggested :
You should always update GUI from GUI thread
For completeness here is how I did:
Because my View is full WPF with no code behind i dont have any controls or form to be call BeginInvoke from, so in the static constructor of my ModelObj, I built an invisible Control from the UI Thread just to be able to call BeginInvoke on it.
So i declared it :
public static Control mInvokeControl;
delegate void MyDelegate();
private MyDelegate _NotifyDelegate;
and then did this in the static constructor of my Object:
mInvokeControl = new Control();
mInvokeControl.CreateControl();
in the normal constructor i Initialize the delegate this way:
_NotifyDelegate = new MyDelegate(this.NotifyByInvoke);
Then after i just use it this way:
ModelObj.mInvokeControl.BeginInvoke(this._NotifyDelegate );
With the method being:
public void NotifyByInvoke()
{
RaisePropertyChanged("Update");
}
Everything works fine !
the COMObj is only accessible from the thread which created it
this is not true. It depends on objects apartment model, but usually you can access it from any thread and it will be either called on same thread or marshaled to proper thread.
I belive that your problem is that you update GUI from background thread which is a major no-no. You should always update GUI from GUI thread. When you update your model object, it still happens on background thread and event of INotifyPropertyChanged interfaces fires on that thread.
You need to synchronize model update to GUI thread by using something like this (WinForms, not WPF - in WPF you should use frm.Dispatcher.BeginInvoke but the problem is the same):
private delegate void ExecuteActionHandler(Action action);
public static void ExecuteOnUiThread(this Form form, Action action)
{
if (form.InvokeRequired) { // we are not on UI thread
// Invoke or BeginInvoke, depending on what you need
// but you said ' and continue immediatly' so BeginInvoke it is
form.BeginInvoke(new ExecuteActionHandler(ExecuteOnUiThread), action);
}
else { // we are on UI thread so just execute the action
action();
}
}
There is another question with similar problem and I have provided additional details there.
I do not know how much data you process, or how much time it takes to perform the GUI part. You may also consider to use locked queues. You can use a queue within your ModelObj to enqueue new tasks by it. This you do with everything you get. Then you may have a timer thread (on the GUI thread).
Here you just check the locked queue, whether there is some new data to display on the GUI. You may dequeue the full list here locally. Then you can also check, whether there is more than one data to display on one component. This way you can skip updates, where you already have newer updates.
And you skip the time for invoking the gui thread to perform the action. You can do several GUI updates at once. If you have too much things to do, you may dequeue only up to a specific number of items to let the GUI react on user interactions. However, you need to check that the queue is not constantly growing.

C# seralization in different thread

I use the XmlSerializer of C# to save and load all models of my application to a file. Because these file operations can take some time, I want do this serialization/deserialization process in a different thread. To do this, I used a delegate and the "BeginInvoke" operation.
The problem is that when all objects are deserialized that they are created by another thread and that all variables in these objects cannot be accessed by the GUI thread.
I know how to access an object from a different thread (by using the Dispatcher.invoke() method) but using this technique to access each variable is not an option in my application.
Is there a solution or easier way to serialize and deserialize objects in a different thread?
Edit:
When all objects are deserialized, the model notifies the view to create UI objects from the deserialized models.
//In the Model:
//when the deserialize operation is ready this handler is executed (not the GUI thread)
void ProjectLoaded(object sender, EventArgs e)
{
ProjectLoadedEventArgs projectLoadedEventArgs = e as ProjectLoadedEventArgs;
m_models = projectLoadedEventArgs.SerializedData.Models;
Notify(null);
}
//In the view:
public void Update(Object o)
{
model.Angle.... -> RIGHT VALUE!!!
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
ResetCanvas();
model.Angle... -> ERROR: The calling thread cannot access this object because a different thread owns it.
}));
}
Deserializing thread has to store objects in some well known to UI thread place. Remember You will have to come up with some synchronization mechanism between threads.
I think I know why You have problems (I read comment to other answer). You deserialize and then notice UI that object is ready. You probably do sth like
UIComponent.DeserializationFinished(). In this method You modify the UI which is not allowed.
[Edit]
Since you've added the exception ("The calling thread cannot access this object because a different thread owns it") in the comment below, it's now clear that GUI controls are being accessed from a non GUI thread. If you search for this on StackOverflow, you will see that it's the direct consequence of refusing to use Dispatcher.Invoke.
I am afraid that you can do only two things:
The preferred way: Use Dispatcher.Invoke to invoke the async deserialization callback on a GUI thread (I realize you've said it's not an option, but it's actually the best way to do it). Remember that Dispatcher.Invoke doesn't access deserialized objects in any special way, it only invokes the callback handler on a GUI thread:
// your async callback
public void ObjectWasDeserialized(IAsyncResult result)
{
_dispatcher.Invoke(new Action<IAsyncResult>(UpdateSomeControl), result);
}
Don't use async callbacks at all, but a Future pattern as described below. But that forces you to poll the result from a GUI thread, which is a bad thing.
It doesn't matter what thread creates an object, its data is still accessible by other threads. What is not recommended is accessing GUI controls from a different thread.
What you probably need is a thread-safe way to signal the GUI thread that an object is ready to be accessed. That can be implemented as a Future object (as explained in this article by Ayende).
Your background thread should create a wrapper around your object, which also contains a ManualResetEvent set to false. After the object has been deserialized successfully, it should signal the event (ManualResetEvent.Set()). UI thread which wants to access the object will have to do it through a property which blocks on this same event until it's signaled. That's logical, since you cannot guarantee that the object will be ready anytime the GUI thread wishes it.
[Edit] Found the article with an implementation. First part is what I was talking about, and ends by defining the InThe class. The part which follows, however, is not necessary at all, and I don't recommend it.
Using the code provided by Ayende, you would have something like:
// a thread (it can even be a GUI thread) requests a future result
Future<SomeObject> future = InThe.Future<SomeObject>(() => Deserialize(file));
// later, in the GUI thread, you access the future wrapper directly
SomeObject result = future.Value; // this will block the calling thread until
// result is ready

Categories