Thursday, 31 October 2013

How to execute delegate synchronously on Windows Phone 8

On WP8 Dispatcher class does not have the Invoke() method to execute delegate synchronously, like it does in .NET Framework 4.5. In fact on WP8 platform this class has only three methods, two overloads of BeginInvoke() for asynchronous delegate execution, and CheckAccess().

To invoke delegate synchronously we can wrap Dispatcher object in DispatcherSynchronizationContext. The Send() method of DispatcherSynchronizationContext should be used to invoke delegate.

SendOrPostCallback used as the first argument in Send() is just to denote delegate type, the delegate used must return void and take one argument.
public delegate void SendOrPostCallback(object state);
Practically it is the same as if it would be Action<T>.

For example here is a code snippet were I launch delegate to be executed on UI thread, as I use Deployment.Current.Dispatcher. The delegate is invoked from non-UI thread which is about to get the display scale factor.

using System.Windows.Threading;


private double m_ScaleFactor = 1.0;

private void DelegateForScaleFactor(object state)
    m_ScaleFactor = 
     ((double)Application.Current.Host.Content.ScaleFactor / (double)100);

public double GetScaleFactor()
    DispatcherSynchronizationContext SyncContext = 
     new DispatcherSynchronizationContext(Deployment.Current.Dispatcher);
     new System.Threading.SendOrPostCallback(DelegateForScaleFactor), null);
    return m_ScaleFactor;