更改按钮文字和点击功能?

时间:2019-04-05 14:12:43

标签: c# winforms

我创建了一个按钮,该按钮将启动“ CMD”进程并ping特定计算机。

我已成功将其发送到Ping,并在单击按钮后来回更改按钮文本,但是我不确定如何在第二次单击时停止ping过程(这是ping -t命令)相同的按钮。

到目前为止,这是我的代码,它选择按钮,单击时更改文本,启动过程并检查错误。我尝试添加“ else”语句并说proc.Kill(),但是在我尝试的所有地方都找不到proc变量。有正确的方法吗?

    public void Btn_Ping_Click_1(object sender, EventArgs e)
    {

        if (Btn_Ping.Text == "Ping")
        {
            Btn_Ping.Text = "Stop Ping";
        }
        else if (Btn_Ping.Text == "Stop Ping")
        {
            Btn_Ping.Text = "Ping";
        }
        th = new Thread(thread1);
        th.Start();
    }

    public void thread1()
    {
        if (Btn_Ping.Text == "Stop Ping")
        {
            try
            {
                string command = "/c ping " + Txt_Main.Text.Trim() + " -t";
                ProcessStartInfo procStartInfo = new ProcessStartInfo("CMD", command);
                Process proc = new Process();
                proc.StartInfo = procStartInfo;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.CreateNoWindow = true;
                proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutPutDataRecieved);
                proc.Start();
                proc.BeginOutputReadLine();
                proc.WaitForExit();

            }
            catch (Exception)
            {
                //If an error occurs within the try block, it will be handled here
            }
        }

        void proc_OutPutDataRecieved(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                string newLine = e.Data.Trim() + Environment.NewLine;
                MethodInvoker append = () => richTextBox1.Text += newLine;
                richTextBox1.BeginInvoke(append);
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

在类级别声明proc(而不是内部thread1)。然后添加到按钮Click事件:

if(proc != null)
{
    if (!proc.HasExited)
        proc.Kill();
    proc = null;
}
else
{
    th = new Thread(thread1);
    th.Start();   
}

答案 1 :(得分:0)

使用Task对象而不是线程。像这样将CancellationToken对象传递给它们:

      private CancellationTokenSource _cts = null;

      public void Btn_Ping_Click_1(object sender, EventArgs e)
      {
         if (Btn_Ping.Text == "Ping")
         {
            _cts = new CancellationTokenSource();
            Btn_Ping.Text = "Stop Ping";
            var task = new Task(() => task1(cts.Token));
            task.Start();
         }
         else if (Btn_Ping.Text == "Stop Ping")
         {
            Btn_Ping.Text = "Ping";
            _cts.Cancel();
         }
      }

      public void task1(CancellationToken ct)
      {
         try
         {
            string command = "/c ping " + Txt_Main.Text.Trim() + " -t";
            var procStartInfo = new ProcessStartInfo("CMD", command);
            var proc = new Process {StartInfo = procStartInfo};
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.CreateNoWindow = true;
            proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutPutDataRecieved);
            proc.Start();
            proc.BeginOutputReadLine();
            while (!proc.WaitForExit(250))
            {
               if (ct.IsCancellationRequested)
               {
                  proc.Kill();
                  return;
               }
            }
         }
         catch (Exception)
         {
            //If an error occurs within the try block, it will be handled here
         }
      }