private async Task Handler() { while (this.IsRunning) { try { using (var socket = new DealerSocket()) using (this.BackendBuffer = new NetMQQueue <TransportMessage>()) using (var poller = new NetMQPoller() { socket, this.BackendBuffer }) using (var monitor = new NetMQ.Monitoring.NetMQMonitor(socket, $"inproc://monitor.forwarderdevice.backend.{Guid.NewGuid().ToString()}", SocketEvents.Connected | SocketEvents.Disconnected)) { socket.Options.Identity = System.Text.Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Replace("-", "").ToLowerInvariant()); socket.ReceiveReady += (sender, e) => { try { var netmqMessage = new NetMQMessage(); if (e.Socket.TryReceiveMultipartMessage(ref netmqMessage)) { var message = netmqMessage.ToMessage(); this.ForwarderDevice.OnBackendReceived(message); this.ForwarderDevice.frontendBuffer.Enqueue(message); } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; this.BackendBuffer.ReceiveReady += (sender, e) => { try { while (this.BackendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero)) { this.ForwarderDevice.OnFrontendForwarded(message); this.ForwarderDevice.OnDiagnosticMessage("Forwarding message to " + this.Endpoint.ToConnectionString()); if (!socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage())) { this.ForwarderDevice.OnDiagnosticMessage("Failed to send message"); } } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } }; monitor.Connected += (sender, e) => { this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket conntected to {this.Endpoint.ToConnectionString()}"); this.IsConnected = true; }; monitor.Disconnected += (sender, e) => { this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket disconntected from {this.Endpoint.ToConnectionString()}"); this.IsConnected = false; }; this.ForwarderDevice.OnDiagnosticMessage($"Attempting to connect to {this.Endpoint.ToConnectionString()}"); monitor.StartAsync(); monitor.AttachToPoller(poller); var pollerTask = new Task(poller.Run); pollerTask.ContinueWith((Task task) => { var ex = task.Exception; this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); this.IsConnected = false; }, TaskContinuationOptions.OnlyOnFaulted); pollerTask.Start(); socket.Connect(this.Endpoint.ToConnectionString()); var start = DateTime.Now; while (!this.IsConnected) { if ((DateTime.Now - start).TotalMilliseconds > 5000) { throw new Exception($"Connection timeout [{this.ServiceName}]"); } await Task.Delay(1000); } while (this.IsConnected && this.IsRunning) { await Task.Delay(1000); } this.ForwarderDevice.OnDiagnosticMessage("Closing dealer socket..."); poller.StopAsync(); socket.Disconnect(this.Endpoint.ToConnectionString()); monitor.DetachFromPoller(); monitor.Stop(); this.IsConnected = false; } if (this.IsRunning) { await Task.Delay(1000); } } catch (Exception ex) { this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace); } } }