我像这个例子一样创建了一个双工服务(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(); } }
显然我不能明确地销毁这个例子中模拟的两个服务实例。但是,如果一个服务的两个实例与两个不同的客户端相关,会发生什么s1
情况s2
?