この例のような二重サービス ( NetTcpBinding
)を作成しました。パブリッシュ/サブスクライブ パターンを使用し、新しいクライアントからの接続要求ごとに、サービスの新しいインスタンス (異なるコールバックを含む) を作成します。この例では、コールバックはイベントとデリゲートを通じて呼び出されます。
ここで、この例を変更したいと思います。クライアントの要求にすぐに応答したくない、つまり、一定の時間間隔の後にコールバック メソッドを呼び出したいとします。この場合、コールバックのメソッドへの参照を維持する必要があります...しかし、その間に一部のクライアントが切断された場合はどうなりますか? サービス インスタンスが破棄され、コールバックも失われます...
私はこの例を書きました:
MySingletonTable
コールバックのメソッドへの参照を格納するデータ構造です。SampleService
サービスではありませんが、サービスのインスタンスをシミュレートします。public delegate void ProcessingHandler(string item, double price, double change); public class MySingletonTable { private static volatile MySingletonTable m_Instance; private static object syncRoot = new object(); private static Dictionary<string, ProcessingHandler> pointersToHandlers; private MySingletonTable() { pointersToHandlers = new Dictionary<string, ProcessingHandler>(); } // Return the singleton instance of this class. public static MySingletonTable Instance { get { if (m_Instance == null) { lock (syncRoot) { if (m_Instance == null) m_Instance = new MySingletonTable(); } } return m_Instance; } } /// The number of the entries in the table. public int Count { get { lock (syncRoot) { return pointersToHandlers.Count; } } } // Add an handler. public void Add(string id, ProcessingHandler handler) { lock (syncRoot) { if (!pointersToHandlers.ContainsKey(id)) pointersToHandlers.Add(id, handler); } } // Get an handler from the table. public ProcessingHandler GetHandler(string id) { ProcessingHandler handler = null; lock (syncRoot) { if (pointersToHandlers.ContainsKey(id)) handler = pointersToHandlers[id]; } return handler; } // Remove the specified handler. public bool Remove(string id) { lock (syncRoot) { return pointersToHandlers.Remove(id); } } } // This class simulates the service. public class SampleService { private static int counter = 0; private int service_i = ++counter; MySingletonTable reference = MySingletonTable.Instance; public SampleService(string id) { reference.Add(id, PriceChange); } private void PriceChange(string item, double price, double change) { // call the callback // ... Console.WriteLine("service_i {0}: {1} {2} {3}", service_i, item, price, change); } } class Program { static void Main(string[] args) { SampleService s1 = new SampleService("abc"); SampleService s2 = new SampleService("def"); MySingletonTable table = MySingletonTable.Instance; ProcessingHandler handler = null; handler = table.GetHandler("abc"); handler("item one", 10, 20); handler = table.GetHandler("def"); handler("item two", 30, 40); Console.ReadLine(); } }
明らかに、この例でシミュレートされた 2 つのサービス インスタンスを明示的に破棄することはできません。しかし、サービスの 2 つのインスタンスが 2 つの異なるクライアントに関連しているs1
としたらどうなるでしょうか?s2