Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#按下按钮时断开回路_C#_Foreach - Fatal编程技术网

C#按下按钮时断开回路

C#按下按钮时断开回路,c#,foreach,C#,Foreach,我有一个简单的C#foreach循环,当按下一个按钮时,我如何打破循环?它不在backgroundWorker线程中,因此我无法使用backgroundWorker.CancellationPending。在表单中创建布尔标志。将事件处理程序附加到按钮click event并在事件处理程序中将标志设置为true 检查循环中的标志,如果它为真,则调用“break”。(更好的选择是使用while循环,而不是在while条件下检查标志的for循环) 显然,for循环需要在某种形式的后台线程上,否则GU

我有一个简单的C#foreach循环,当按下一个按钮时,我如何打破循环?它不在backgroundWorker线程中,因此我无法使用backgroundWorker.CancellationPending。

在表单中创建布尔标志。将事件处理程序附加到按钮click event并在事件处理程序中将标志设置为true

检查循环中的标志,如果它为真,则调用“break”。(更好的选择是使用while循环,而不是在while条件下检查标志的for循环)

显然,for循环需要在某种形式的后台线程上,否则GUI将无法响应。如果您不知道如何执行此操作,请查看或。如果确实使用BackgroundWorker,则可以使用内置的CancelAsync()方法,而不是编写自己的cancel标志

[编辑:正如其他人(如下)所指出的,并进行了更深入的讨论;您确实需要在访问bool之前锁定它或将其标记为volatile]


[在开始循环之前,不要忘记设置标志的正确状态。]

这里有一个不太好的解决方案

在循环的每次迭代中调用
Application.DoEvents()
。在按钮上单击将变量设置为True,并在循环中检查该变量。如果为真,则中断,否则继续


正如我所说,这不是一个很好的解决办法
Application.DoEvents()
可能非常危险。这里最好的选择是有一个后台线程。

你可以使用DoEvents,就像Aamir建议的那样,作为一个快速修复


为了获得更具可扩展性和可维护性的解决方案,您需要将工作转移到单独的线程。然后,让一个按钮单击事件设置一个标志来停止循环就相当简单了。另一方面,将结果传回UI线程需要做更多的工作。

foreach循环是否在单独的线程上使用?或者在UI线程上?循环是否在另一个线程上运行?如果循环在UI线程上,则在包含循环的函数完成之前,不会到达按钮单击事件处理程序。我同意,如果您只想定期检查事件,则该事件为过。为什么会出现否决票?人们是否认为按下按钮终止中间循环是不明智的?显然,标志必须是可变的,或者访问必须同步。efraim,为什么需要同步对简单布尔字段的访问?用户不能很好地同时按下启动循环的按钮和取消循环的按钮,是吗?因为编译器可以合法地优化任何这样的访问,如果它认为合适的话。@Simon:最坏的情况实际上是它将永远循环,因为编译器永远不会尝试访问变量。即使是布尔,当从另一个线程访问时,需要
(作为内存屏障)或
易失性
,以保证它将被重新读取;有可能显示它在寄存器中卡住的示例,否则:我同意。这不是一个很好的解决方案。不要使用DoEvents。使用后台工作线程或ThreadPool.QueueUserWorkItem()+1将for循环正确地放置在后台线程上,以获得实际工作的内容,即使这是一个不可扩展的相当丑陋的解决方案。。。您可以向它添加一个计数器,并每n:th次迭代调用DoEvents以减少性能损失。