进程输出比使用cmd慢得多

时间:2014-10-13 12:38:50

标签: c# winforms process plink

我需要将PLink作为一个进程运行,作为WinForm应用程序的一部分 这是我的代码

     public void RunProcess(string FileName, string Arguments, bool EventWhenExit , bool IsWaitBeforeStart = true )
     {
        process = new Process();
        process.OutputDataReceived += new DataReceivedEventHandler(OnDataReceivedEvent);//**
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.FileName = FileName; // Gets or sets the application or document to start.
        process.StartInfo.Arguments = Arguments;//Gets or sets the set of command-line arguments to use when starting the application      
        if (IsWaitBeforeStart) Thread.Sleep(5000);
        if (EventWhenExit)
        {
            process.EnableRaisingEvents = true;

            process.Exited += new EventHandler(myprocess_Exited);

        }           
        process.Start();
        process.BeginOutputReadLine();
        PID = process.Id;
        ProcessTimeOut.Enabled = true;
        ProcessInputStream = process.StandardInput;
        ProcessTimeOut.Enabled = false;            
    }


private void OnDataReceivedEvent(object sender, DataReceivedEventArgs e)
{
 //prints to screen using control.invoke
 //add data to a string list
}

我的设置包含一个telnet服务器,我需要在其上运行一些命令并解析结果 如果我从cmd运行应用程序,它会在一秒内打印结果(大约50行) 但如果我使用我的代码运行它,它需要将近7秒!

从我的理解process.start()和通过cmd运行应该是相同的 所以问题应该出现在我的代码或逻辑中

可能是什么问题?

1 个答案:

答案 0 :(得分:1)

好的,在 Vajura 评论的帮助下,我已经制作了一个简单的(变化的)缓冲区来实现简单的消费者/生产者模式

在RunProcess中:

     public void RunProcess(string FileName, string Arguments, bool EventWhenExit , bool IsWaitBeforeStart = true )
 {
   //... same code as before 
   PollingService();    
 }

第二次更改事件DataReceivedEventHandler

将数据存储到缓冲区(并停止调用打印到UI) 代码类似于ProcessLog.Add(e.Data);

现在让第二个Thread在缓冲区上运行:

        private void PollingService()
    {
        var T = new Thread (()=>
        {
            while (true)
            {
                if (ProcessLogIndex < ProcessLog.Count)
                {
                    lock (this)
                    {
                        var tempList = ProcessLog.GetRange(ProcessLogIndex, ProcessLog.Count - ProcessLogIndex);
                        ProcessLogIndex = ProcessLog.Count;
                        foreach (var cell in tempList)
                        {

                            string ToSend = !string.IsNullOrEmpty(cell) ? (cell.Contains('$') ? cell.Substring(cell.LastIndexOf('$')) : cell) : "";
                            onDataOutputFromProcess(this, ToSend, Proc.ToString());
                        }

                    }

                }
                Thread.Sleep(1000);
            }
        });
        T.IsBackground = true;
        T.Start();
    }