2011-09-22 81 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的),線程池線程或長期線程將按上述方式出隊並評估更新。這有很多可能的變化和優化。