вывод процесса намного медленнее чем с cmd

1

Мне нужно запустить 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 должны быть одинаковыми, поэтому проблема должна быть где-то в моем коде или логике

что может быть проблемой?

  • 0
    IsWaitBeforeStart правда может быть?
  • 0
    Я хотел бы, чтобы это была проблема :(
Показать ещё 8 комментариев
Теги:
winforms
process
plink

1 ответ

1
Лучший ответ

Хорошо, поэтому с помощью комментария Vajura я сделал простой (различный) буфер для реализации простого шаблона потребителя/производителя

внутри RunProcess:

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

второе изменение события DataReceivedEventHandler

для хранения данных в буфер (и прекращения вызова печати в пользовательский интерфейс) код является чем-то вроде ProcessLog.Add(e.Data);

теперь для второго потока для выполнения над буфером:

        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();
    }
  • 0
    Я делаю это немного иначе, я запускаю второй поток перед рабочим потоком и делаю это только один раз, но вы также можете сделать это таким образом. У меня есть несколько вопросов: каждый раз, когда вы хотите отправить данные в свой интерфейс, вы начинаете новую тему, верно? Или PollingService выполняется только один раз? Кроме того, как вы останавливаете поток, когда он заканчивает свою работу?
  • 0
    pollingService запускается один раз для каждого процесса, когда я хочу отправить данные в пользовательский интерфейс, я запускаю событие, которое обрабатывает весь сбор данных из различных процессов, обрабатывает некоторую логику (на какой экран отправлять в основном) и запускает другое событие на уровне пользовательского интерфейса, я не уверен если это лучше всего выполнить, но для меня это имело смысл, когда я это написал. как только процесс прекратился, я также удаляю эту (pollingService) нить

Ещё вопросы

Сообщество Overcoder
Наверх
Меню