private void Process() { Pipe.WaitForConnection(); var msgWatch = new Stopwatch(); while (true) { Tuple <Protocol.Request, TaskCompletionSource <Protocol.Response>, JavaEditor> item = null; lock (WorkItems) { if (WorkItems.Count == 0) { Thread.Sleep(100); // trottle down continue; } // Dequeue next item while (true) { item = WorkItems.Dequeue(); // Peek at the queue to see if the LIFO request was invalidated by a newer request of the same type if (WorkItems.Count != 0 && LIFORequests.Contains(item.Item1.requestType) && WorkItems.Any(x => x.Item1.requestType == item.Item1.requestType)) { item.Item2.SetCanceled(); continue; // There is another request in the queue of the same type; will ignore this one } break; } } try { Telemetry.Client.Get().TrackEvent( "App.MessageSend", new Dictionary <string, string> { { "Protocol.RequestType", item.Item1.requestType.ToString() } }, null); if (item.Item3 != null) { item.Item3.Fire_OperationStarted(item.Item1); } msgWatch.Restart(); Pipe.WriteMessage(item.Item1); var response = Pipe.ReadMessage(); msgWatch.Stop(); if (item.Item3 != null) { item.Item3.Fire_OperationCompleted(item.Item1, response); } if (response != null) { Telemetry.Client.Get().TrackEvent( "App.MessageReceived", new Dictionary <string, string> { { "Protocol.ResponseType", response.responseType.ToString() } }, null); } if (response != null && response.responseType == Protocol.Response.ResponseType.FileParseStatus && response.fileParseResponse.status == false) { // Parse failed; time to shutdown the server // Clear queue lock (WorkItems) { while (WorkItems.Count != 0) { var citem = WorkItems.Dequeue(); citem.Item2.SetCanceled(); } } // Notify editors and other listeners that the server is about to go down if (TerminatedAbnormally != null) { TerminatedAbnormally(this, response); } // Exit loop break; } Telemetry.Client.Get().TrackMetric("App.Metric.MessageResponse", msgWatch.ElapsedMilliseconds, 1, msgWatch.ElapsedMilliseconds, msgWatch.ElapsedMilliseconds, new Dictionary <string, string> { { "Protocol.RequestType", item.Item1.requestType.ToString() } }); item.Item2.SetResult(response); } catch (IOException e) { item.Item2.SetException(e); Telemetry.Client.Get().TrackException(e, new Dictionary <string, string> { { "Protocol.RequestType", item.Item1.requestType.ToString() } }, null); } // If "bye", exit the thread since the child process will exit anyway if (item.Item1.requestType == Protocol.Request.RequestType.Bye) { break; // will exit thread } } if (JavaPkgSrv != null) { JavaPkgSrv.Close(); } Pipe.Disconnect(); Pipe.Dispose(); }