2013-08-20 74 views
3

我使用VB.NET和我有:如何打破循環與一個單一的按鈕點擊

  • 一個Start按鈕
  • 一個Stop按鈕
  • 一個While循環

當按下Start按鈕時,While循環開始。我想在按下按鈕Stop時停止循環。

我曾嘗試使用Applications.DoEvents,但當Stop按鈕被按下時,循環停止兩次

以下爲使用Applications.DoEvents

Dim stopclick As Boolean = False 

Private Sub btnPlay_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlay.Click 
    btnForward.Enabled = False 
    btnStop.Enabled = True 
    While 
     ' Perform the while statements 
     If stopclick = True Then 
      stopclick = False 
      Application.DoEvents() 
      Exit While 
     End If 
    End While 
End Sub 

Private Sub btnStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStop.Click 
    stopClick = True 
End Sub 
  1. 我的代碼,我已經使用Application.DoEvents不正確?
  2. Application.DoEvents之外,還有哪些其他選項?我怎樣才能停止一個單一的Stop按鈕點擊循環?

回答

2

你需要把調用Application.DoEvents以外的If語句,就像這樣:

While True 
    Application.DoEvents() 
    ' Perform the while statements 
    If stopclick Then 
     stopclick = False 
     Exit While 
    End If 
End While 

Stop_Click不會有要處理的機會,直到你叫DoEvents,因此,與你的方式,stopClick永遠不會被設置爲True

但是,更大的問題在於,調用DoEvents完全是非常糟糕的做法,如果您不太小心,可能會導致一些非常難以修復的錯誤。如果循環是在後臺線程中執行的話會好得多。查看BackgroundWorker組件,以便爲WinForm項目輕鬆實現線程化機制。你會在你的表單設計器的工具箱中找到它。

這裏有一個如何與BackgroundWorker組件做一個例子:

Dim stopclick As Boolean = False 

Private Sub btnPlay_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlay.Click 
    btnForward.Enabled = False 
    btnStop.Enabled = True 
    BackgroundWorker1.RunWorkerAsync() 
End Sub 

Private Sub btnStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStop.Click 
    stopClick = True 
End Sub 

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    stopClick = False 
    While Not stopClick 
     ' Perform the while statements 
    End While 
End Sub 

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
    btnForward.Enabled = True 
    btnStop.Enabled = False 
End Sub 
+0

我試圖放置Application.DoEvents()If語句之外。但是,我仍然需要雙擊停止按鈕。 1)如何使'停止按鈕'被單擊來打破循環? 2)你是否知道使用BackgroundWorker的循環打樣示例? – user2150279

+0

是的,我只是測試它,並得到相同的行爲。我不確定這是爲什麼,但無論如何,這還不是正確的方法,所以我不會浪費時間去解決問題。我用'BackgroundWorker'添加了一個例子。 –

+0

尊敬的@Steven Doggart,感謝您的上述代碼。我已經測試過,但是我得到了一個錯誤。在while語句中,我有一個來自Form1的變量_ChartControl1_。當代碼運行時,它顯示一個錯誤:「跨線程操作無效:控制'Form1'從一個線程訪問,而不是它創建的線程。」以下是While語句中的行示例:'ChartControl1.Series.Add(series3) Me.Controls.Add(ChartControl1)'。錯誤消息顯示在'Me.Controls.Add(ChartControl1)' – user2150279

0

您可以通過使用stopClick爲您的病情顯著簡化您while循環:

While Not stopClick 
    Application.DoEvents() 
End While 
+0

此代碼片段對我來說工作得很好 - 我在循環中執行了一些代碼。我不同意上面的Application.DoEvents註釋。我發現處理多線程/後臺工作者更容易出錯並且更難調試/維護。 – rheitzman

+1

@rheitzman雖然我同意這段代碼很容易編寫和維護,但對於多線程應用程序還是有一些東西要說 - 特別是在涉及到UI時。在單個線程中運行代碼將阻止UI。這對於小型應用程序來說可以,但對於任何類型的可伸縮性,多線程方法都是必需的。 –

+0

@rheitzman如果使用'BackgroundWorker'太難了,可能是因爲您沒有將業務邏輯和數據模型從UI邏輯中正確分離出來。只要你設計好你的代碼,它應該是相當微不足道的。關鍵要注意的是,你不能從後臺線程訪問UI。因此,在調用線程之前,您需要在UI之外準備數據,然後在事實之後從結果更新UI。如果您確實需要直接訪問UI,則始終可以使用「Invoke」,但理想情況下您不需要。 –

0

我知道這是一箇舊的線程,但我發現了一個簡單的解決方法。將一個CheckBox添加到表單中(如果有意義的話,它甚至可以「離開表單的一側」)。

Private Sub btnStopLoop_Click(sender As System.Object, e As System.EventArgs) Handles btnStopLoop.Click 

    chkEndLoop.CheckState = CheckState.Checked 

End Sub 

然後,在河套想退出:

Do Until chkEndLoop.CheckState = CheckState.Checked 

    'Do Stuff Here 

Loop 

只要CheckBox.CheckState = CheckState.Unchecked,循環將繼續,但是當複選框成爲選中,退出循環

-1

您必須在循環開始時使用btnstop.focus()。這一定會解決你的問題。

實施例:

Dim stopclick As Boolean = False 

Private Sub btnPlay_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlay.Click 
    btnForward.Enabled = False 
    btnStop.Enabled = True 
    btnStop.Focus() ' new code--------------------- 
    While 
     ' Perform the while statements 
     If stopclick = True Then 
      stopclick = False 
      Application.DoEvents() 
      Exit While 
     End If 
    End While 
End Sub 

Private Sub btnStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStop.Click 
    stopClick = True 
End Sub