2011-08-19 87 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只是爲了確保您的代碼不會每次點擊執行多次,如果它已經在運行。