示例#1
0
        public Runner(Args args = null)
        {
            args = args ?? new Args();

            this.handler = Logger.Trace;
            this.delay   = Math.Max(0, args.IdleMsDelay);
            this.idle    = args.IdleAction;

            if (idle == null)
            {
                this.delay = -1;
            }

            queue = new LockedQueue <Command>();

            thread = new Thread(Loop);
            thread.IsBackground = true;
            thread.Name         = args.ThreadName;
            thread.Start();
        }
示例#2
0
        public static void Interactive(IStream io, Args args)
        {
            var thread = Thread.CurrentThread.Name;
            var reader = new Runner(new Runner.Args()
            {
                ThreadName = string.Format("{0}_R", thread)
            });
            var erroer = new Runner(new Runner.Args()
            {
                ThreadName = string.Format("{0}_W", thread)
            });

            using (reader)
                using (erroer)
                {
                    var process = new DaemonProcess(args);
                    //eof below must close process immediatelly
                    //to ensure exited message happens after real exit
                    using (process)
                    {
                        io.WriteLine("Process {0} has started", process.Id);
                        var queue = new LockedQueue <bool>();
                        reader.Run(() =>
                        {
                            var line = process.ReadLine();
                            while (line != null)
                            {
                                Logger.Trace("<o:{0} {1}", process.Id, line);
                                io.WriteLine(line);
                                line = process.ReadLine();
                            }
                            Logger.Trace("<o:{0} EOF", process.Id);
                        });
                        reader.Run(() => queue.Push(true));
                        erroer.Run(() =>
                        {
                            var line = process.ReadError();
                            while (line != null)
                            {
                                Logger.Trace("<e:{0} {1}", process.Id, line);
                                line = process.ReadError();
                            }
                            Logger.Trace("<e:{0} EOF", process.Id);
                        });
                        erroer.Run(() => queue.Push(true));
                        while (true)
                        {
                            //non blocking readline needed to notice reader exit
                            var line = io.TryReadLine(out var eof);
                            if (eof)
                            {
                                Logger.Trace("EOF input > process");
                            }
                            if (eof)
                            {
                                break;
                            }
                            if (line != null)
                            {
                                Logger.Trace("i:{0}> {1}", process.Id, line);
                                process.WriteLine(line);
                            }
                            if (queue.Pop(1, false))
                            {
                                break;
                            }
                        }
                    }
                    //previous loop may swallow exit! by feeding it to process
                    //unit test should wait for syncing message below before exit!
                    io.WriteLine("Process {0} has exited", process.Id);
                }
        }