public static class SyncNotifyExtension
{
    public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<PropertyChangedEventArgs> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
    {
        Contract.Requires<ArgumentNullException>(host != null);
        Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
        Contract.Requires<ArgumentNullException>(eventRaiser != null);
        dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
        if (dispatcher.Thread == Thread.CurrentThread)
        {
            eventRaiser(new PropertyChangedEventArgs(propertyName));
        }
        else
        {
            if (wait)
            {
                dispatcher.Invoke(eventRaiser, new PropertyChangedEventArgs(propertyName));
            }
            else
            {
                dispatcher.BeginInvoke(eventRaiser, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<string> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
    {
        Contract.Requires<ArgumentNullException>(host != null);
        Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
        Contract.Requires<ArgumentNullException>(eventRaiser != null);
        dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
        if (dispatcher.Thread == Thread.CurrentThread)
        {
            eventRaiser(propertyName);
        }
        else
        {
            if (wait)
            {
                dispatcher.Invoke(eventRaiser, propertyName);
            }
            else
            {
                dispatcher.BeginInvoke(eventRaiser, propertyName);
            }
        }
    }
    public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<object, PropertyChangedEventArgs> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
    {
        Contract.Requires<ArgumentNullException>(host != null);
        Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
        Contract.Requires<ArgumentNullException>(eventRaiser != null);
        dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
        if (dispatcher.Thread == Thread.CurrentThread)
        {
            eventRaiser(host, new PropertyChangedEventArgs(propertyName));
        }
        else
        {
            if (wait)
            {
                dispatcher.Invoke(eventRaiser, host, new PropertyChangedEventArgs(propertyName));
            }
            else
            {
                dispatcher.BeginInvoke(eventRaiser, host, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    public static void SyncNotify(this INotifyPropertyChanged host, string propertyName, Action<object, string> eventRaiser, bool wait = false, Dispatcher dispatcher = null)
    {
        Contract.Requires<ArgumentNullException>(host != null);
        Contract.Requires<ArgumentException>(string.IsNullOrWhiteSpace(propertyName));
        Contract.Requires<ArgumentNullException>(eventRaiser != null);
        dispatcher = dispatcher ?? System.Windows.Threading.Dispatcher.CurrentDispatcher;
        if (dispatcher.Thread == Thread.CurrentThread)
        {
            eventRaiser(host, propertyName);
        }
        else
        {
            if (wait)
            {
                dispatcher.Invoke(eventRaiser, host, propertyName);
            }
            else
            {
                dispatcher.BeginInvoke(eventRaiser, host, propertyName);
            }
        }
    }
}