【问题标题】:Observe WCF service call with RX使用 RX 观察 WCF 服务调用
【发布时间】:2013-11-30 10:53:15
【问题描述】:

我有一个 WCF 心跳服务接受来自客户端的保持活动。如果保持活动未在指定时间内到达,则会引发超时并采取一些措施。现在,我正在尝试简化使用 System.Threading.Timer 的现有代码,并将其替换为基于 RX 的解决方案。我缺少的是如何将 WCF 服务方法类转换为可观察的。我考虑的有以下几点:

  • 在 WCF 服务中实现 IObservable 并缓存观察者作为订阅参数传递,可能不是一个好主意和丑陋的代码
  • 这样使用主题:

    
     Subject s1 = new Subject();
     s1.Timeout(TimeSpan.FromSeconds(3))
       .Subscribe(_ => { }, ex => Console.WriteLine("Timeout at " + DateTime.Now));
    
    

    Console.WriteLine("Hertbeat at: " + DateTime.Now); s1.OnNext(Unit.Default); Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("Hertbeat at: " + DateTime.Now); s1.OnNext(Unit.Default);

    这可行,但可能在生产代码中使用主题不是一个好主意。
    • 在服务实现中使用事件:

    
    class HeartbeatService
    {
      public void Heartbeat()
      {
        OnHeartbeatArrived();
      }
    
    

    public event Action HeartbeatArrived;

    protected virtual void OnHeartbeatArrived() { Action handler = HeartbeatArrived; if (handler != null) handler(Unit.Default); } }

然后使用 RX

HeartbeatService heartbeatService = new HeartbeatService();
Observable.FromEvent<Unit>(action => heartbeatService.HeartbeatArrived += action,
                           action => heartbeatService.HeartbeatArrived -= action)
  .Timeout(TimeSpan.FromSeconds(3))
  .Subscribe(_ => { },
             ex => Console.WriteLine("Timeout " + ex + ", at " + DateTime.Now));

Console.WriteLine("Heartbeat at: " + DateTime.Now);
heartbeatService.Heartbeat();
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine("Heartbeat at: " + DateTime.Now);
heartbeatService.Heartbeat();
Console.WriteLine("Should timeout now");

我也不喜欢这个解决方案,WCF 服务中的事件似乎是多余的。 在 RX 中是否有这样做的好方法,或者我想在这里滥用 RX?

【问题讨论】:

    标签: c# wcf system.reactive


    【解决方案1】:

    Throttle 运算符是 Rx 中心跳算法的关键部分。基本思想是建立一个包含警报的流,只要心跳到达,该警报就会被抑制。更多详细信息请参见我的博文:http://www.zerobugbuild.com/?p=230

    【讨论】:

    • 谢谢詹姆斯。我使用 Timeout 而不是 Throttle,因为它终止了序列:introtorx.com/Content/v1.0.10621.0/…。在您的博客文章中,您建议使用主题,而我的问题是如何消除对主题的需求。但也许主题是要走的路,没有更清洁和更好的解决方案。
    • 你必须以某种方式进入单子......主题,FromEventXXX......随便。最后都是一样的。坏事是不必要地跳进跳出 monad - 这是 Subject 滥用的常见形式。您可以使用 Throttle + Take(1) 来终止 btw。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多