Comment casser une boucle avec un seul clic
Je suis en utilisant VB.NET et j'ai:
- un
Start
bouton - un
Stop
bouton - un
While
boucle
Lorsque le Start
bouton est pressé, le While
la boucle commence. Je veux arrêter la boucle lorsque le Stop
le bouton est pressé.
J'avais essayé d'utiliser Applications.DoEvents
, mais la boucle s'arrête lorsque la Stop
bouton est pressé deux fois.
Ci-dessous mon code à l'aide de 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
- Je n'ai utilisé
Application.DoEvents
mal? - Quelles sont les autres options en plus
Application.DoEvents
? Comment puis-je arrêter la boucle avec un seulStop
cliquez sur le bouton?
OriginalL'auteur user2150279 | 2013-08-20
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin pour mettre l'appel à
Application.DoEvents
à l'extérieur de votreIf
déclaration, comme ceci:La
Stop_Click
de ne pas avoir une chance d'être traitée jusqu'à ce que vous appelezDoEvents
, donc, de la façon qu'il avait,stopClick
ne serait jamais mis àTrue
.Cependant, le plus gros problème, ici, est que l'appel à
DoEvents
, à tous, est très mauvaise pratique et peut conduire à des très difficiles à corriger les bugs si vous n'êtes pas très prudent. Il serait beaucoup mieux si la boucle est exécutée dans un thread d'arrière-plan. Découvrez laBackgroundWorker
composante d'un programme facile à mettre en œuvre mécanisme de threading pour WinForm projets. Vous le trouverez dans la boîte à outils de votre concepteur de formulaire.Voici un exemple de comment le faire avec le
BackgroundWorker
composant:Ouais, je l'ai juste testé et a reçu le même comportement. Je ne suis pas sûr pourquoi, mais en tout cas, ce n'est pas la bonne façon de le faire de toute façon, je ne voudrais pas perdre de temps à essayer de le comprendre. J'ai ajouté un exemple avec le
BackgroundWorker
.Cher @Steven Doggart, je vous remercie pour votre code ci-dessus. J'avais testé, cependant j'ai une erreur. Dans l'instruction while, j'ai une variable ChartControl1 de Form1. Lorsque le code est exécuté, il affiche une erreur: "inter-threads non valide: le Contrôle 'Form1' accessible à partir d'un thread autre que le thread qu'il a été créé." Voici un exemple de lignes dans l'instruction While:
ChartControl1.Series.Add(series3) Me.Controls.Add(ChartControl1)
. Le message d'erreur s'affiche à l'Me.Controls.Add(ChartControl1)
Qui est correct. Vous ne pouvez pas accéder à tous les éléments d'INTERFACE utilisateur (par exemple, le contrôle, formulaires) dans le thread d'arrière-plan. Comme je l'ai dit dans mon autre commentaire sur la réponse de Luc, vous avez besoin de l'éloigner du modèle de données et la logique métier de votre INTERFACE utilisateur, de sorte que de le faire à partir d'un thread séparé est possible sans toucher à aucun contrôle. Si, toutefois, vous avez vraiment besoin d'accéder à un contrôle, vous pouvez le faire en appelant au thread principal avec la forme du
Invoke
méthode. Par exemple:Invoke(Sub() ChartControl1.Series.Add(series3))
.OriginalL'auteur Steven Doggart
Vous pouvez simplifier votre boucle while considérablement en utilisant stopClick en tant que votre condition:
Alors que je suis d'accord que ce code est facile à écrire et à maintenir, il y a quelque chose à dire pour une application multi-thread, surtout quand une de l'INTERFACE utilisateur est impliqué. L'exécution de votre code dans un thread unique va bloquer l'INTERFACE utilisateur. Ce sera très bien pour de petites applications, mais pour toute sorte d'évolutivité, un multi-fileté approche est nécessaire.
Si vous utilisez le
BackgroundWorker
est trop difficile, c'est probablement parce que vous n'avez pas correctement séparées votre logique métier et à votre modèle de données à partir de votre logique de l'INTERFACE utilisateur. Tant que vous avez conçu votre code bien, il devrait être tout à fait banale. L'important à retenir est que vous ne pouvez pas accéder à l'INTERFACE de la thread d'arrière-plan. Par conséquent, vous avez besoin pour préparer les données, au large de l'INTERFACE utilisateur, avant d'appeler le fil, puis mise à jour de l'INTERFACE utilisateur à partir des résultats, après le fait. Si vous avez vraiment besoin pour accéder à l'INTERFACE directement, vous pouvez toujours utiliserInvoke
, mais, idéalement, vous ne serez pas en avoir besoin.OriginalL'auteur Luke M Willis
Je sais que c'est un vieux thread, mais j'ai trouvé une solution simple. Ajouter une Case à cocher pour la forme (il peut même être "du côté de la forme," si cela fait sens).
Ensuite, dans la Boucle que vous souhaitez quitter:
Tant que le
CheckBox.CheckState = CheckState.Unchecked
, la Boucle continue, mais lorsque la Case à cocher devient Cochée, la Boucle de SortieOriginalL'auteur rogue5pawn
Vous devez utiliser
btnstop.focus()
au début de la boucle. Ce sera assurez-vous de résoudre votre problème.Exemple:
OriginalL'auteur Linendra Soni