/// <summary>
        /// Starts the channels for this kernel.
        ///
        /// This will create the channels if they do not exist and then start
        /// them(their activity runs in a thread). If port numbers of 0 are
        /// being used(random ports) then you must first call
        /// :meth:`start_kernel`. If the channels have been stopped and you
        /// call this, :class:`RuntimeError` will be raised.
        /// </summary>
        /// <param name="shell"></param>
        /// <param name="iopub"></param>
        /// <param name="stdin"></param>
        /// <param name="hb"></param>
        public void StartChannels(bool shell = true, bool iopub = true, bool stdin = true, bool hb = true)
        {
            if (shell)
            {
                ShellChannel.Start();

                ShellThread = new Thread(() => EventLoop(ShellChannel))
                {
                    Name = "Shell Channel"
                };
                ShellThread.Start();
            }

            if (iopub)
            {
                IoPubChannel.Start();

                IoPubThread = new Thread(() => EventLoop(IoPubChannel))
                {
                    Name = "IoPub Channel"
                };
                IoPubThread.Start();
            }

            if (stdin)
            {
                StdInChannel.Start();
                AllowStdin = true;

                StdInThread = new Thread(() => EventLoop(StdInChannel))
                {
                    Name = "StdIn Channel"
                };
                StdInThread.Start();
            }
            else
            {
                AllowStdin = false;
            }

            if (hb)
            {
                HbChannel.Start();
            }

            // Now that the channels have started, collect the kernel information
            if (shell && ShellChannel.IsAlive)
            {
                KernelInfo();
            }
        }