【问题标题】:Notify WPF UI with WCF callback message使用 WCF 回调消息通知 WPF UI
【发布时间】:2023-03-19 10:49:01
【问题描述】:

我在执行 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. ViewModel 实现:

    公共类 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() 从未执行过。

有没有人确切地看到问题出在哪里? 提前致谢

【问题讨论】:

    标签: wpf wcf mvvm caliburn.micro


    【解决方案1】:

    您为回调指定了UseSynchronizationContext = false,这意味着所有回调都在线程池上调用。 UI 不允许从任何线程更新自身,但调度程序之一。因此,您需要将 MessageLog 属性的更新编组到调度程序线程上。见this answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      • 2023-04-11
      • 1970-01-01
      相关资源
      最近更新 更多