用WCF回调消息通知WPF UI



我在执行WCF服务时遇到了更新WPF UI的问题,该服务在每个操作执行后都会向客户端发送消息。我使用WSDualHttpBinding。当我为来自服务的每条消息显示一个消息框时,同样的实现可以完美地工作。但这不能用于更新UI。

PS:我使用MVVM模式和Caliburn.micro我的实现简化了:

1 -接口:

    public interface IMyContractCallback
{
    [OperationContract]
    void OnCallback();
}

 [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
public interface IMyContract
{
    [OperationContract]
    void DoSomething();
}
2 -服务:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MyService : IMyContract
{
    public void DoSomething()
    {
        DoJob1();
        var callbackChannel = OperationContext.Current.GetCallbackChannel<IMyContractCallback>();
        callbackChannel.OnCallback();
        DoJob2();
    }
}

3 -客户:

    回调实现:

public delegate void ClientNotifiedEventHandler(object sender, ClientNotifiedEventArgs e);

 public class ClientNotifiedEventArgs : EventArgs
    {
                private readonly string _message;
                public string Message { get { return _message; } }
                public ClientNotifiedEventArgs(string message)
                {
                    this._message = message;
                }
    }

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
        public class MyCallbackClient : IMyContractCallback
        {
public event ClientNotifiedEventHandler ClientNotified;
            public void OnCallback()
            {
                 if (ClientNotified != null)
                        {
                            ClientNotified(this, new ClientNotifiedEventArgs(log));
                        }
            }
        }
  1. 视图模型实现:

    公共类MyViewModel{

        private string _message = "Loading..";
        public string MessageLog
        {
            get { return _message; }
            set
            {
                _message = value;
                NotifyOfPropertyChange(() => MessageLog);
            }
        }
        public void DoTheJob()
        {
            var callback = new DbLoaderCallback();
            callback.ClientNotified += Callback_ClientNotified;
            var context = new InstanceContext(callback);
            using (var serviceClient = new MyService(context))
            {
                serviceClient.DoSomething();
            }
        }
        private void Callback_ClientNotified(object sender, ClientNotifiedEventArgs e)
        {
            MessageLog += " n";
            MessageLog += e.Message;
        }    
    

    }

这里,当调用callbackChannel.OnCallback();(在MyService上),当我们到达NotifyOfPropertyChange(() => MessageLog)时,它去到客户端,在MyViewModel上;它不会继续执行。所以DoJob2()从未执行过。

有谁知道到底是什么问题吗?提前感谢

您为回调指定了UseSynchronizationContext = false,这意味着所有回调都在线程池上调用。UI不允许从任何线程更新自己,只有调度程序一个。因此,您需要将MessageLog属性的更新封送到调度程序线程上。

最新更新