С# GUI зависает после запуска консольного приложения

Я делаю приложение, которое запускает ping и отображает результат в текстовом поле. Когда я нажимаю кнопку запуска ping, графический интерфейс зависает, и в текстовое поле ничего не выводится. Почему этот GUI зависает понятно, GUI ждет завершения работы консольного приложения. Не понимаю, как тогда реализовать вывод в текстовое поле из консольного приложения.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace WindowsFormsApp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Class1 ping = new Class1();
            ping.startPing();
            string output = ping.output();
            richTextBox1.AppendText(output + "\n");
            richTextBox1.Update();
        }

        static private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }

    class Class1
    {
        private Process p = new Process();

        public void startPing()
        {
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = "c:/windows/system32/ping";
            p.StartInfo.Arguments = "8.8.8.8 -t";
            p.Start();
        }

        public string output()
        {
            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            return output;
        }
    }
}

c#
person Michael    schedule 22.03.2019    source источник
comment
Графический интерфейс зависает, потому что вы запускаете пинг в том же потоке, что и графический интерфейс, тем самым блокируя его обновление до тех пор, пока ваша операция не завершится, вы можете захотеть запустить новый поток или фоновый рабочий и запустить на нем пинг   -  person MindSwipe    schedule 22.03.2019
comment
Как вы думаете, что делает p.WaitForExit();? Предлагает ли документация альтернативный подход? docs.microsoft. com/en-us/dotnet/api/   -  person mjwills    schedule 22.03.2019
comment
Так же есть масса примеров по вытягиванию результатов из консоли в c#   -  person BugFinder    schedule 22.03.2019
comment
Попробуйте использовать событие p.Exited (не забудьте его разрешить - p.EnableRaisingEvents = true;) и сбросьте p.WaitForExit();   -  person Dmitry Bychenko    schedule 22.03.2019


Ответы (1)


Этот код будет полезен для решения вашего запроса.

  private void button1_Click(object sender, EventArgs e)
  {
          var worker = new BackgroundWorker();
          worker.DoWork += (o, ea) =>
          {
                Class1 ping = new Class1();
                ping.startPing();
                string output = ping.output();
                richTextBox1.AppendText(output + "\n");
                richTextBox1.Update();

          };
          worker.RunWorkerCompleted += (o, ea) =>
          {
                //You will get pointer when this worker finished the job.
          };
          worker.RunWorkerAsync();
    }

Дайте мне знать, если возникнут какие-либо проблемы после реализации с вашим источником.

person ShSakariya    schedule 22.03.2019
comment
Просто размещение кода не помогает ОП понять решение. Пожалуйста, предоставьте объяснение вместе с кодом. - person T_Bacon; 22.03.2019