private static void InitWorkflow()
        {
            _reactionRegistrar.Init(_pageMonitor.CurrentPage);

            _socket.Message += (sender, args) =>
            {
                _workflow.Queue(args.Message);
            };

            _socket.SocketStarted += (sender, args) =>
            {
                _workflow.Start(_messageFinder, _socket);
            };

            _pageMonitor.PageChanged += (sender, args) =>
            {
                _reactionRegistrar.Init(args.NewPage);
                var msg = UIMessage.Create <PageChanged>().ToJson();
                _socket.Send(msg);
            };

            if (_loggingEnabled)
            {
                _socket.Trace += (sender, args) =>
                {
                    Debug.WriteLine($"{AppName}: {args.Description}");
                };
            }

            _pageMonitor.Start();
        }
        /// <summary>
        /// Execute the queued message.
        /// </summary>
        private void Consumer()
        {
            try
            {
                lock (_lock)
                {
                    ConsumerThreads++;
                }

                foreach (var message in _queue.GetConsumingEnumerable(_cancellationSource.Token))
                {
                    if (_queue.IsCompleted)
                    {
                        return;
                    }

                    var request = Parse(message);
                    // skip null request
                    if (request == null)
                    {
                        continue;
                    }

                    var context = new UIMessageContext
                    {
                        Message     = message,
                        ShouldQueue = false,
                        Request     = request,
                        Response    = null
                    };

                    ExecuteDesignAction(context);

                    // add it back for later processing
                    if (context.ShouldQueue)
                    {
                        _queue.TryAdd(message, AddWaitTimeMs, _cancellationSource.Token);
                        Task.Delay(QueueDelayTimeMs).Wait();
                    }
                    else
                    {
                        try
                        {
                            var json = context.Response?.ToJson();

                            if (!string.IsNullOrWhiteSpace(json))
                            {
                                _socket.Send(json);
                            }
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }

                    context.Response = null;
                }
            }
            catch (OperationCanceledException)
            {
                // ignored
            }
        }