【问题标题】:breaking out of my infinite loop打破我的无限循环
【发布时间】:2010-11-26 12:01:36
【问题描述】:

我的 UI 表单中有两个按钮,一个用于启动,一个用于停止,并且我有一个无限循环,它在我的类名程序中以方法执行某些函数。启动按钮由调用此方法的用户单击要执行无限循环,我需要在用户单击停止按钮时打破这个无限循环,之后我的编译器将打破这个无限循环并进入按钮停止点击内的代码。 我正在尝试使用Application.DoEvents() 方法,如果我的无限循环代码在开始按钮单击内,这很好用,但是如果我的无限循环代码在我创建的新类中,即程序,如何使用Application.DoEvents() 方法来打破这个无限循环。

例子:

namespace inFiniteLoopTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        bool stopBtnClk = false;
        bool startBtnClk = false;

        private void StartBtn_Click(object sender, EventArgs e)
        {
            stopBtnClk=false;

            startBtnClk = true;

            while(true)
            {
                //some code to be executed
                Application.DoEvents();
                if (stopBtnClk == true)
                {
                   break;
                }
            }
        }

        private void StopBtn_Click(object sender, EventArgs e)
        {
            stopBtnClk = true;
            if (startBtnClk == true)
            {
                //Application.Exit();
                MessageBox.Show("success");

            }

        }

这很好。

但是

public class programs
{    
    public static void infiniteLoop(bool stopBtnClick)
    {    
        while(true)
        {
            //some code to be executed
            Application.DoEvents();
            if (stopBtnClk == true)
            {
                break;
            }
        }
    }    
} 

//and my UI code to call this class is
namespace inFiniteLoopTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        bool stopBtnClk = false;
        bool startBtnClk = false;

        private void StartBtn_Click(object sender, EventArgs e)
        {
            stopBtnClk=false;    
            startBtnClk = true;
            programs.infiniteLoop(stopBtnClk);
        }

        private void StopBtn_Click(object sender, EventArgs e)
        {
            stopBtnClk = true;
            if (startBtnClk == true)
            {
                //Application.Exit();
                MessageBox.Show("success");
            }
        }            
    }

但这不起作用。

即使在单击停止按钮时编译器显示消息“成功”,但调试器仍然说在我的表单中运行。 我希望我的问题很清楚。 我恳请您尽快回答我的问题并摆脱这个问题! 如果您特别带线程来,我会公开接受您的回答。

对不起,我是 C# 的初学者,但我需要继续学习。

谢谢!!

【问题讨论】:

  • 如果这个问题只与 C# 相关,为什么要将此问题标记为 [java][php][c++][c]? (我已经对其进行了编辑以仅包含正确的标签)。
  • 请重新格式化代码。选择整个块,并在其上使用“代码示例”功能,可能需要执行两次,您还将看到它最终的样子。
  • 你应该使用线程来完成这项工作。
  • 你确定第二个编译吗?您在programs.infiniteLoop 中访问stopBtnClk。 stopBtnClk 不是类程序的参数或字段。
  • @MrFox 这就是我想要的,然后帮助我解决这个问题,使用 thread.10q

标签: c#


【解决方案1】:

不要阻塞 GUI 线程。您必须使用 Application.DoEvents() 来更新 GUI 的事实表明设计不佳。在单独的工作线程中完成工作。

BackgroundWorker 注定要完成这样的任务。

【讨论】:

  • 没有足够的向上箭头来回答这个问题。
【解决方案2】:

像这样更改您的无限循环方法的签名:

public static void infiniteLoop(ref bool stopBtnClick) ...

【讨论】:

  • 点击开始按钮里面的方法是programs.infiniteLoop(stopBtnClk);调用这个函数。错误参数“1”必须与“ref”关键字一起传递
  • 像这样用 ref 传递它:programs.infiniteLoop(ref stopBtnClk);
【解决方案3】:

您提供的代码确实很难阅读,但据我所知,当您创建无限循环时:while(looping) // do stuff

然后,当您按下停止按钮时,将 bool 变量循环设置为 false,它将跳出循环并显示消息。

【讨论】:

  • 一旦编译器通过开始按钮获得无限循环,它不会退出该循环,它不会考虑单击它后的动作/事件(停止按钮单击)。那是我的问题,我需要在单击按钮时处理该事件的技巧。尤其是使用线程。
【解决方案4】:

在第二个代码 sn-p 中,无限循环在一个接受布尔值作为参数的子例程中启动。该子例程如何获得第二次查看该布尔值的机会?它只“看到”一次该值,当时它是错误的。这是一个范围界定问题。

【讨论】:

  • 我认为这是对事件处理程序方法 Application.DoEvents();但是可能是错误的,但是如果我单击停止按钮,它会显示“成功”消息,但背后的原因是我的表单表明我仍在运行。但是开始调试和不调试开始之间有什么区别,我对这些词感到困惑也。
【解决方案5】:

为什么不使用无限循环,而是使用由按钮确定的开始停止条件?

我想你可以有一个变量,就叫它

bool stop_loop = false 

和你的循环

while(!stop_loop){ //CODE HERE }

现在,当您单击第一个按钮(开始)时,您将调用方法(无论它在哪里)来启动循环。在您单击停止按钮并且 stop_loop 的值变为 True 之前,循环似乎是无止境的。

HTH

【讨论】:

  • @SubniC:即使我做到了,它也不会考虑停止按钮点击的事件
  • @subnic 我认为您需要将 volatile 添加到您的 bool 声明中。
  • @Johnathan Brown 为什么不使用 volatile 关键字?它会对性能产生一些影响,但这是从不使用它的充分理由吗?它也用于example in the MSDN,类似于我们的案例。
  • @وليدتاجالدين 如果你确切地知道它的作用并且你 100% 确定你想在多个线程中使用它,那么继续(也许我自己措辞不正确)。但是,在这种情况下,您不需要这样做。创建一个委托并允许线程知道变量,而不是抛出 volatile 关键字,以便所有线程都可以访问它。我建议阅读这篇文章:theburningmonk.com/2010/03/… MSDN 对 volatile 的定义非常具有误导性……
  • @Johnathan Brown 谢谢你的好文章。根据这篇文章 - 以及我对 volatile 的了解 - 它可能会给人一种错误的安全感,但正如你所提到的,在某些情况下 - 当一个人真正知道他在做什么时 - 使用 volatile 关键字是安全的。我们的案例 - 仅使用变量来终止线程 - 我认为是安全的,也是您为我提供的文章中提到的示例,用于说明 volatile 是安全的情况。
猜你喜欢
  • 2013-03-08
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 1970-01-01
相关资源
最近更新 更多