从另一个类中停止循环

时间:2011-08-19 21:29:07

标签: c# .net loops

所以我有两个事件处理程序button1_Click()和button2_Click()

在button1_Click()中,我运行的内容如下:

toGet = textbox1.Text;
got = 0;

while (got <= toGet)
{
  //DoStuff
}

但是button2_Click应该是一个停止按钮,并提前停止按钮1。 我该怎么做? 谢谢您的帮助。我在这里看到了this article,但无法让它发挥作用。

3 个答案:

答案 0 :(得分:1)

Windows.Forms回答

最不复杂的方法是:

private bool m_stop;
private void button1_Click (object s, EventArgs ea)
{
   try
   {
   //  Don't forget to disable all controls except the ones you want a user to be able to click while your method executes.

      toGet = textbox1.Text;
      got = 0;

      while (got <= toGet)
      {
        Application.DoEvents (); 
        // DoEvents lets other events fire.  When they are done, resume.
        if (m_stop)
           break;
        //DoStuff
      }

   finally
   {
      //  Enable the controls you disabled before.
   }
}

private void button2_Click (object s, EventArgs ea)
{
   m_stop = true;
}

它具有让你在UI线程上执行button1_Click的独特优势,仍然让UI响应你的停止按钮。

它有一个缺点,你必须防止重入。当button1_click已经执行时,如果他们点击你的按钮1会发生什么!?!?

编辑:我使用的另一种方法是使用Timer而不是循环。然后,stop方法只是停止计时器。

答案 1 :(得分:0)

根据我的理解,如果我错了,请纠正我,你是单线程。 有线,但您可以检查While循环内的单个布尔值,就像帖子建议的那样。

可能是为了让生活更轻松(也许这就是“无法让它工作”的意思)是在内部循环调用

1)Windows窗体:Application.DoEvents()

2)WPF(有点棘手):DoEvents in WPF

这是呼吸系统。

答案 2 :(得分:0)

您需要在新线程中的button1内启动该过程,并且当您将button2标记时,将本地变量设置为false以停止循环。像:

using System.Threading;

private volatile bool _requestStop = false;
private readonly object _oneExecuteLocker = new object();    


private void OnButton1Click(ojbect sender, EventArgs e)
{
    new Thread(() =>
    {
        if (Monitor.TryEnter(_oneExecuteLocker))
        {//if we are here that is means the code is not already running..
            try
            {
                while (!_requestStop)
                {
                    //DoStuff
                } 
            }
            finally
            {
                Monitor.Exit(_oneExecuteLocker);
            }
        }
    }){ IsBackground = true }.Start();
}

private void OnButton2Click(object sender, EventArgs e)
{
    _requestStop = true;
}

注意:

  • 如果您想在新创建的线程中更新UI控件,则应使用contorl.Invoke(/*the code get/set or call method in the UI*/)
  • Monitro.Enter只是为了确保您的代码在每次点击时都不会执行多次,如果它已在运行。