Создание и активное использование процесса без замораживания основного потока. - PullRequest
0 голосов
/ 11 октября 2019

В настоящее время я пытаюсь создать новый процесс NodeJS и, пока он выполняется, поместите вывод его консоли в мое текстовое поле winform.

Каждый раз, когда выполняется этот процесс, он останавливает основной поток, как будто форма ожидает этогопроцесс для выхода. После того, как процесс закрывается, это когда консольный вывод добавляется в текстовое поле.

То, что я пытаюсь достичь, - это одновременно запустить этот процесс узла в фоновом режиме и получить все, что выводится в текстовом поле.

Редактировать 1:

Мне удалось запустить консоль без замораживания основного потока, но вывод отображается только при закрытии процесса

Мой текущий код:

    private void Btn_connect_Click(object sender, EventArgs e)
        {
            if(backgroundWorker1.IsBusy != true)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            nodeProcess = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "node.exe";
            startInfo.Arguments = @"path" + " arg1 arg2 arg3";
            startInfo.UseShellExecute = false;
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.RedirectStandardOutput = true;
            nodeProcess.StartInfo = startInfo;

            nodeProcess.Start();

            while (worker.CancellationPending != true)
            {
                Thread.Sleep(200);
                AddText(nodeProcess.StandardOutput.ReadToEnd());
                worker.ReportProgress(1);
            }

            e.Cancel = true;
        }

        public void AddText(string text)
        {
            if(txt_log.InvokeRequired)
            {
                txt_log.Invoke(new Action<string>(AddText), new object[] { text });
                return;
            }

            txt_log.Text += "\n " + text;
        }

1 Ответ

1 голос
/ 11 октября 2019

Вместо BackgroundWorker вы можете попробовать использовать Process.BeginOutputReadLine, Process.OutputDataReceived и Process.Exited.

void StartProcess()
{
    Process nodeProcess = new Process();
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.FileName = "node.exe";
    startInfo.Arguments = @"path" + " arg1 arg2 arg3";
    startInfo.UseShellExecute = false;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.RedirectStandardOutput = true;
    nodeProcess.StartInfo = startInfo;

    nodeProcess.EnableRaisingEvents = true;
    nodeProcess.Exited += nodeProcess_Exited;
    nodeProcess.OutputDataReceived += nodeProcess_OutputDataReceived;

    nodeProcess.Start();
    nodeProcess.BeginOutputReadLine();
}

void nodeProcess_Exited(object sender, EventArgs e)
{
    // Do something when the process exits, if you need to.
    // You'll want to check InvokeRequired before you modify any of your form's controls.
}

void nodeProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if (txt_log.InvokeRequired)
    {
        txt_log.Invoke(new Action<string>(AddText), new object[] { e.Data });
        return;
    }
    txt_log.Text += "\n " + e.Data;
}
...