【问题标题】:Change button text AND function on click?单击时更改按钮文本和功能?
【发布时间】:2019-04-05 14:12:43
【问题描述】:

我创建了一个按钮,用于启动“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);
            }
        }
    }

【问题讨论】:

  • 不能只在类中声明Process,在其他方法中调用Kill吗?
  • 呼应我在下面所说的话,我不敢相信我没想过要这样做。谢谢你。这里的新开发人员,我经常错过这样的小事情:(
  • stackoverflow.com/questions/30249873/… 这似乎暗示运行 CMD 来 ping 不会响应 proc.Kill() 尝试直接运行它。

标签: c# winforms


【解决方案1】:

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

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

【讨论】:

  • 哇,我不敢相信我没想到只在课堂上声明 proc。嗯,谢谢。
  • 我试着说 Process proc = new Process();在课堂上,以及只是说Process proc;并在下面启动它,但都没有工作。初始 ping 一直在继续。
【解决方案2】:

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

      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
         }
      }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多