2009-08-17 5 views
2

ユーザーが入力した値に基づいて特定のサイクル数(1〜576)をループするWhileループを使用しています。ユーザーが「スタート」ボタンをクリックすると起動しますが、「Escape」キーを使用してキャンセルできるようにしたいと考えています。Whileループを途中でキャンセルする

しかし、ループが行われているときに、プログラムがキーを押さないようにすることはできません。

Private Sub OnGlobalKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles kh.KeyDown 

     lblInput.Text = String.Format("'{0}' Code:{1}", e.KeyCode, CInt(e.KeyCode).ToString()) 


     If e.KeyCode = CType(27, Keys) Then 
        count = 0 
        loops = 0 
     End If 
    End Sub 

私のループは

Private Sub RUNLOOP() 
      While loops >= 1 
        ' my code that runs in the loop 
        loop = loop - 1 
      End While 
End Sub 

ループは私のキー押下が登録していない実行している間は、そうでない場合は罰金登録します。あなたのループの場所インサイド

答えて

-1

次のコード:

Application.DoEvents() 
+3

これは.NETでは悪い考えです。 BackGroundWorkerクラスがとても使いやすく、リエントラント問題につながる可能性があるときには、この操作を行う必要はありません。 –

+0

.NETでの従来の設計手法はこれを悪い考え方にしていますが、この質問の文脈では、正解です。代替案は、彼のアプリケーションの完全な再設計で彼を助けることです。あなたはそれをボランティアしたいですか? –

+0

私は、BackGroundWorkerを追加して単一のメソッドをリファクタリングすることで、 "(完全な)アプリケーションの再設計"を構成することを知らなかった。 OPはUIを生かし続ける方法を尋ねましたが、これは悪い(怠惰な)解決策です。 –

-3
While counter <= 10 
     ' skip remaining code in loop only if counter = 7 
     If counter = 7 Then 
      Exit While 
     End If 

     counter += 1 
     End While 
+0

これは解決策ではありません... –

+0

Exit Whileの使用を嫌っています。論理ブロックは論理条件、つまりcounter> 10で正しく完了するはずです。出口がコードに埋め込まれていると、この例では見やすいですが、これはほんの数行の単純な線ですが、実際にはそうではありません。 Stefan Rusekははるかに洗練されたソリューションです。 – DaveF

5

あなたは(=フォームを再描画とせ/リサイズmaking sure your GUI keeps responsive、バックグラウンドスレッドでwhileループのコードを実行するためにBackgroundWorkerを使用して考えていあなたは実行中の作業の取り消しを実装したやり方でユーザに「手を届ける」)Application.DoEventsをループの中に入れなくても、この動作を「偽」することができますか?

既に.NET Framework 4.0をお使いの場合は、BackgroundWorkerの代わりにparallel programmingを試してみてください。

+0

さて、私はBackgroundWorkerスレッドを使ってみましたが、私はすべての設定が完了していると思っていますが、今は "クロススレッド操作が有効ではありません:コントロール 'cmb_x'それは、元のループのほとんどすべてのコードを変更することです。 – user157603

+1

しかしそれは正しいことです。あなたはこのことがどのように機能するのか理解する必要があります –

+0

あなたは 'Control.InvokeRequired'をチェックアウトしましたか?例については、http://weblogs.asp.net/justin_rogers/articles/126345.aspxを参照してください。 – peSHIr

2

これには2通りの方法があります。ループに別のスレッドを使用するか、Application.DoEvents()を使用することができます。糸のアプローチは、一般的にあなたに最高の結果を与えるでしょう。

スレッド:

あなたは単に実行を停止するためにループを伝えるためにStopLoop()を呼び出します。ループがスレッド間で正しく設定されていることを確認するには、Interlockedクラスを使用する必要があるため、loop = 0に設定しないでください。

Private Sub RunLoop() 
    Dim loop As Action = AddressOf InternalRunLoop 
    loop.BeginInvoke(null, null) 
End Sub 

Private bStopLoop As Boolean 

Private Sub InternalRunLoop() 
    While loops >= 1 And Not bStopLoop 
    ' my code that runs in the loop 
    loop = loop - 1 
    End While 
End Sub 

Private Sub StopLoop() 
    bStopLoop = True 
End Sub 

DoEvents関数:

呼び出すApplication.DoEvents()を処理するウィンドウのスレッド上のすべての保留中のイベントが発生します。ループの各反復に時間がかかる場合でも、アプリケーションは応答しないようにユーザーに表示されます。そのため、スレッド化されたアプローチが推奨されます。

Private SubRunLoop() 
    While loops >= 1 And Not bStopLoop 
    ' my code that runs in the loop 
    loop = loop - 1 
    Application.DoEvents() 
    End While 
End Sub 
関連する問題