2011-08-19 143 views
-1

所以,我有两个事件处理程序的button1_Click()和button2_Click()停止循环从另一个类

在的button1_Click()我有一些运行这样的:

toGet = textbox1.Text; 
got = 0; 

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

但button2_Click应该成为停止按钮,并提前停止按钮1。 我该如何解决这个问题? 感谢您的帮助。我在这里看到了this article,但无法使其工作。

+0

您是否在单线程中运行,正如您链接到的问题的接受答案中所述? – Oded

+0

是的,的确是我。 – Someone

+0

你做了什么尝试失败? – Tigran

回答

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而不是循环。然后,停止方法只是停止计时器。

+0

当我这样做时,我得到名称“m_stop”不存在于此上下文中 in button1 – Someone

+0

将此字段添加到您的类中:'private bool m_stop;' –

+0

定时器+1。但考虑到你的“单线程规则”,你只能使用System.Windows.Forms.Timer。如果这是winforms(还不是很清楚) – Tigran

0

尽我所知,纠正我,如果我错了,你在单线程。 有线,但您可以在您的While循环内检查单个布尔值,就像提示的那样。

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

1)Windows窗体:Application.DoEvents()

2)WPF(小位更棘手):DoEvents in WPF

这使呼吸系统。

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只是为了确保您的代码不会每次点击执行多次,如果它已经在运行。