2011-09-22 76 views
1

我有一个服务正在侦听来自上游系统的位置更新。现在有多个这个位置的消费者更新。如何在C#服务中执行多个发布计划?

  • 一位消费者都想尽快
  • 一位消费者希望得到更新,每30秒
  • 一位消费者希望得到更新,当50次更新累积
  • 一位消费者想获得更新当更新累计50次或更早更新时更新。

上面可以随时更改或新的变化可以添加?

我该如何使这种可配置的,可扩展的以及我应该使用什么样的编程方法。

我在C#开发,窗口服务

+0

订阅者(IEvent * ev,枚举UpdateRate) – kenny

+0

Kenny,你能更具体吗?我没有给你评论。 – Ocean

+0

创建委托来订阅IEventWhaterver并拥有一个描述多久更新界面的枚举。考虑为秒添加计数,#udpates或枚举的单位。 – kenny

回答

0

这听起来像你所描述的一个场景,该服务发布源(服务本身是一个用户)和服务重新广播该信息之间的中介到用户,但按他们的时间表。因此,假设更新是单个位置更新,而不是像滚动平均值和缓冲(例如,每30秒钟的汽车的最近位置,而不是自从最近30秒以来的所有位置)那样的某种聚合,那么,您需要为每个订阅者保留一些信息:

  • a 订阅。谁是消费者?我如何通知它? (例如回叫,回复队列等)
  • a 规范。消费者需要什么以及什么时候需要? (例如每50个滴答)
  • 状态
    • 时间自从作为服务接收更新最后发送
    • ...

最后发送更新的

  • 号,对于每个消费者,它必须针对来自源的每个更新的状态评估规格;是这样的:

    if (consumer.Spec.Matches(consumer.State, updateMessage) 
        SendUpdate(consumer.Subscription.Callback, updateMessage) 
    

    以上假设你的规范是由服务直接执行(即消费者在处理或规范连载,并且可以通过该服务进行反序列化如果不是的。情况下,你的天赋也许可以代表一个DSL(例如,可分析表示,该服务器可以编译成一些它可以执行)。另一种方法是思维的规范作为指令集。例如,

    public enum FrequencyUnit 
    { 
        SecondsSinceLastSend, 
        UpdatesSinceLastSend, 
    } 
    
    public class Frequency 
    { 
        public double Value { get; set; } 
        public FrequencyUnit Unit { get; set; } 
    } 
    
    public class Operator 
    { 
        Every, // Unary: e.g. every update; every 10 sec; every 5 updates 
        Or, // Nary: e.g. every 50 or every 20 sec (whichever's first) 
        And, // Nary: e.g. 19 messages and 20 sec have passed 
        // etc. 
    } 
    
    public class UpdateSpec 
    { 
        public Frequency[] Frequencies { get; set; } 
        public Operator Operator { get; set; } 
    } 
    

    这些都是非常灵活,并且可以在服务器代码中进行配置,或者可以在内置的b上进行配置阅读XML或其他东西。这些也可以在注册后从消费者本身传递给服务。例如,一个IService.Register()可能暴露接受订阅和规范的接口。

    最后一位是可扩展性。我描述了每个更新中的消费者服务循环。这不会很好地扩展,因为循环可能会阻止从源接收更新,或者如果与源异步,至少可能会比处理更快地累积更新。

    解决这个问题的一个策略是为每个订户维护的信息添加一个内部队列。该服务在收到更新后会将其排入每个内部队列。然后服务任务(基于TPL的),线程池线程或长期线程将按上述方式出队并评估更新。这有很多可能的变化和优化。