This will be a short and technical post about a problem I just solved using information from Stack Overflow answers. Because none of those discussions is actually responding my question I will make this note about what I found.
Creating background workers and other threads may lead into a cross thread invoke errors when dispatching property notifications.
For example Windows Phone Pivot Application is using MVC architecture. In my case I needed to communicate with a Bluetooth device and this required thread based property management.
The Bluetooth-device message was receiver, but property setter raised cross thread access exception in NotifyPropertyChanged… using a standard code like this:
public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } }
So I needed a solution to invoke the handler in the right way.
In Stack Overflow first I found a solution for Windows Applications, but not Windows Phone applications 🙂
public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { var e = new PropertyChangedEventArgs(propertyName); foreach (EventHandler h in handler.GetInvocationList()) { var synch = h.Target as ISynchronizeInvoke; if (synch != null && synch.InvokeRequired) synch.Invoke(h, new object[] { this, e }); else h(this, e); } } }
Then I needed to find a solution avoid using ISynchronizeInvoke (it’s not present in windows phone application)
The simplest solution was to directly use Deployment.Current.Dispatcher.BeginInvoke, but this I forgot because windows phone development is not my main occupation.
public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { Deployment.Current.Dispatcher.BeginInvoke(() => { handler(this, new PropertyChangedEventArgs(propertyName)); }); } }
I hope this will help you as it’s helping me.
Leave a Reply