简体   繁体   English

C#按下按钮后退出循环

[英]C# Break out of loop on button press

I have a simple C# foreach loop, how can I break out of the loop when a button is pressed? 我有一个简单的C#foreach循环,当按下按钮时如何突破循环? It is not in a backgroundWorker thread so I can't use backgroundWorker.CancellationPending. 它不在backgroundWorker线程中,因此我无法使用backgroundWorker.CancellationPending。

Create a boolean flag in the form. 在表单中创建一个布尔标志。 Attach an event handler to the buttons click event and set the flag to true in the event handler. 将事件处理程序附加到按钮单击事件,并在事件处理程序中将标志设置为true。

Check for the flag in the loop and if it's true, call "break". 检查循环中的标志,如果是,则调用“break”。 (A better option would be to use a while loop instead of a for loop with the check of the flag in the while condition) (更好的选择是使用while循环而不是for循环,并在while条件中检查标志)

Obviously the for loop will need to be on some form of background thread otherwise the GUI won't be responsive. 显然,for循环需要在某种形式的后台线程上,否则GUI将不会响应。 If you don't know how to do this, check out either ThreadPool.QueueUserWorkItem or the BackgroundWorker . 如果您不知道如何执行此操作,请查看ThreadPool.QueueUserWorkItemBackgroundWorker If you do use a BackgroundWorker you can use the inbuilt CancelAsync() method instead of coding your own cancel flag. 如果您确实使用BackgroundWorker,则可以使用内置的CancelAsync()方法,而不是编写自己的取消标记。

[Edit: As pointed out by others (below) and discussed in more depth here and here ; [编辑:正如其他人所指出的那样(下文),并在这里这里进行更深入的讨论; you do need to either lock before accessing the bool or mark it as volatile] 你需要在访问bool之前锁定或将其标记为volatile]

[Don't forget to set the correct state of the flag before you start the loop.] [在开始循环之前,不要忘记设置正确的标志状态。]

Here is a not-so-good solution. 这是一个不太好的解决方案。

Call Application.DoEvents() in every iteration your loop. 在循环的每次迭代中调用Application.DoEvents() On Button-Click set a variable to True and in loop check that variable. 在按钮上单击将变量设置为True并在循环中检查该变量。 If it is true, break otherwise continue. 如果是真的,否则继续打破。

As I said, this is not a very good solution. 正如我所说,这不是一个很好的解决方案。 Application.DoEvents() can be very dangerous. Application.DoEvents()可能非常危险。 The best option here to do is to have a background thread. 这里最好的选择是拥有一个后台线程。

You can use DoEvents, as Aamir suggested, as a quick fix. 您可以像Aamir建议的那样使用DoEvents作为快速修复。

For a more scalable and maintainable solution, you need to move the work to a separate thread. 要获得更具可扩展性和可维护性的解决方案,您需要将工作移至单独的线程。 Then it's rather trivial to have a button click event set a flag to stop the loop. 然后,按钮单击事件设置一个标志来停止循环是相当简单的。 On the other hand, there is a bit more work to communicate the result back to the UI thread. 另一方面,将结果传回UI线程还有一些工作要做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM