private void HandleMessage(ICDEThing arg1, object arg2) { var msg = (arg2 as TheProcessMessage).Message; if (msg == null) { return; } var messageName = TheCommRequestResponse.ParseRequestOrResponseMessage(msg, out var messageParameters, out var correlationToken); switch (messageName) { case nameof(MsgChatHello): { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgChatHello>(msg); if (request != null) { // Messages come in on a .Net Threadpool thread, so need to dispatch it to the WPF main thread before we can access any WPF controls this.Dispatcher.InvokeAsync(() => { var chatMessage = new ChatMessage { MessageId = correlationToken, SenderName = request.SenderName, Message = request.Message, SeenBy = 0, Sent = msg.TIM, Received = DateTimeOffset.Now, }; MessageList.Items.Insert(0, chatMessage); }); TheCommRequestResponse.PublishResponseMessageJson(msg, new MsgChatHelloResponse { Acknowledged = true }); } else { TheCommRequestResponse.PublishResponseMessageJson(msg, new MsgChatHelloResponse { Acknowledged = false }); } } break; case nameof(MsgChatHello) + "_RESPONSE": { var request = TheCommRequestResponse.ParseRequestMessageJSON <MsgChatHelloResponse>(msg); if (request != null) { this.Dispatcher.InvokeAsync(() => { if (request.Acknowledged) { int i = 0; foreach (var item in MessageList.Items) { var chatMessage = item as ChatMessage; if (chatMessage != null) { if (chatMessage.MessageId == correlationToken) { chatMessage.SeenBy++; MessageList.Items.RemoveAt(i); MessageList.Items.Insert(i, chatMessage); break; } } i++; } } else { MessageBox.Show($"Somebody ({msg.ORG}) rejected our message {correlationToken}"); } }); } else { // Somebody is sending MsgChatHelloResponse messages in an unknown/incompatible format, or somebody rejected a message for some reason this.Dispatcher.InvokeAsync(() => { MessageBox.Show($"Received invalid MsgChatHelloResponse: {msg}"); }); } } break; } }