/// <summary> /// This is a helper mehtod that connects the Scribbler on the specified /// COM port. It waits for the connection to complete, and re-throws any /// exceptions generated by the Scribbler service. /// </summary> /// <param name="comPort"></param> private static void connectWaitForScribbler(string comPort) { ManualResetEvent evt = new ManualResetEvent(false); waitForService(new ServiceInfoType(scribbler.Contract.Identifier), delegate(ServiceInfoType info) { brickService = info; evt.Set(); }); evt.WaitOne(Params.DefaultRecieveTimeout, false); if (brickService == null) { throw new MyroInitException("Could not find Scribbler service"); } var scribPort = DssEnvironment.ServiceForwarder <scribbler.ScribblerOperations>(new Uri(brickService.Service)); DispatcherQueue queue = new DispatcherQueue("init", new Dispatcher()); try { if (comPort != null) { int comNumber; if (comPort.ToLower().StartsWith("com")) { comNumber = Int32.Parse(comPort.Substring(3)); } else { throw new MyroInitException("COM port string must be of the format com2, com5, etc."); } RSUtils.ReceiveSync(queue, scribPort.Replace(new scribbler.ScribblerState() { ComPort = comNumber }), Params.DefaultRecieveTimeout); } DssEnvironment.LogInfo("calling reconnect..."); RSUtils.ReceiveSync(queue, scribPort.Reconnect(), Params.DefaultRecieveTimeout); DssEnvironment.LogInfo("reconnect returned"); } catch (Exception) { throw; } finally { queue.Dispose(); } }
/// <summary> /// Helper method that waits for a service to start and runs a handler when it does. /// This subscribes to and queries the DSS directory. /// </summary> /// <param name="serviceInfo"></param> /// <param name="handler"></param> private static void waitForService(ServiceInfoType serviceInfo, Handler <ServiceInfoType> handler) { var dirPort = DssEnvironment.ServiceForwarder <directory.DirectoryPort>(new Uri("dssp.tcp://localhost/directory")); var notPort = new directory.DirectoryPort(); // Keep this flag to only run the handler once bool ranHandler = false; Object lockObj = new Object(); // Subscribe first, then query, to make sure we don't miss the service registering itself DssEnvironment.LogInfo("Subscribing to directory"); Arbiter.Activate(DssEnvironment.TaskQueue, Arbiter.Choice( dirPort.Subscribe( new directory.SubscribeRequest() { QueryRecordList = new List <ServiceInfoType>() { serviceInfo }, NotificationCount = 1 }, notPort, typeof(directory.Insert)), delegate(SubscribeResponseType r) { DssEnvironment.LogInfo("Subscribed to directory!"); // Run handler if the service starts and we get the subscription notification DssEnvironment.LogInfo("Activating subscription receive"); Arbiter.Activate(DssEnvironment.TaskQueue, Arbiter.Receive <directory.Insert>(false, notPort, delegate(directory.Insert ins) { DssEnvironment.LogInfo("Got subscription notification!"); lock (lockObj) { if (ranHandler == false) { new Thread(new ThreadStart(delegate() { handler.Invoke(ins.Body.Record); })).Start(); ranHandler = true; } } })); }, delegate(Fault f) { lock (lockObj) { if (ranHandler == false) { new Thread(new ThreadStart(delegate() { handler.Invoke(null); })).Start(); ranHandler = true; } } DssEnvironment.LogError("Fault received while subscribing to directory: " + Strings.FromFault(f)); })); // Query directory, run handler if the service is already started DssEnvironment.LogInfo("Querying directory"); Arbiter.Activate(DssEnvironment.TaskQueue, Arbiter.Choice( dirPort.Query(new directory.QueryRequest() { QueryRecord = serviceInfo }), delegate(directory.QueryResponse r) { DssEnvironment.LogInfo("Queried directory!"); lock (lockObj) { if (ranHandler == false && r.RecordList.Length > 0) { new Thread(new ThreadStart(delegate() { handler.Invoke(r.RecordList[0]); })).Start(); ranHandler = true; } } }, delegate(Fault f) { //lock (lockObj) //{ // if (ranHandler == false) // { // new Thread(new ThreadStart(delegate() { handler.Invoke(null); })).Start(); // ranHandler = true; // } //} DssEnvironment.LogError("Fault received while querying directory: " + Strings.FromFault(f)); })); }