views:

473

answers:

2

I have some UI code that needs to be updated from my background presenter thread. So, I do the following: from my background thread, I set my property in the UI: _ui.ConnectionStatus = "A";

then, my set is as follows:

public string ConnectionStatus

{

set{

if (Dispatcher.CheckAccess())

ConnectionStatusTxt.Content = value;

else {

Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                                  {ConnectionStatusTxt.Content = value;}));

}

} }

I get the following error: "The calling thread cannot access this object because a different thread owns it." My understanding was that Dispatcher takes care of invoking on different threads, so this error puzzles me a little. Thanks!

A: 

You don't say what object this setter is executing inside, but it looks like this object's Dispatcher is not the same as ConnectionStatusTxt's dispatcher, i.e. the object containing the setter is owned by a different thread from the ConnectionStatusTxt control.

Try using ConnectionStatusTxt.Dispatcher in your CheckAccess and Invoke statements.

itowlson
I tried using ConnectionStatusTxt's dispatcher with no luck. Thanks for pointing out an inconsistency -- I updated my post, hopefully it makes a little more sense now.
Lenik
+3  A: 

Another question: what type is value? is this a string? I could imagine that the error might be that value is in fact a UIElement (maybe a Label?) that you create in which case the exception refers to the value object and not to your user control.

Patrick Klug
the value is indeed a string. Actually, as I am debugging this right now, passing in strings appears to be working; however, when you pass in ImageSource to a property that otherwise looks identical (assignm is diff: TechIcon.Source = value; where Source is ImageSource) -- that does not work now.
Lenik
that makes sense as ImageSource is a DependencyObject and can therefore only be modified from the Thread it was created on. If you create your ImageSource in the background thread this will not work. You will need to create the ImageSource in your standard UI thread.
Patrick Klug
You could also try to Freeze your ImageSource object. See documentation for the Freezable class.Thread safety: a frozen Freezable object can be shared across threads
Patrick Klug
Patrick, you are completely right in your last comment. One I "froze" my ImageSource object everything worked! Thank you!
Lenik