C# 如何停止while循环?

C# 如何停止while循环?,c#,C#,我想在C#中使用以下代码,但我似乎无法摆脱它。如果用户按键或移动啮齿动物(又名鼠标),我想终止应用程序。这是我的代码(不要笑!) 您可以使用break语句退出循环 编辑:好的,我收回国旗的东西 您的“忙碌等待”策略设计不佳。相反,您应该使用触发的事件处理程序: 按键盘 当鼠标移动时 在这两种情况下,您都可以通过终止应用程序来响应。关键字将终止循环。在本例中,当您点击要停止循环的案例时,您只需使用break按键事件处理程序需要将bgNotClicked变量设置为false 如果啮齿动物被鼠标移

我想在C#中使用以下代码,但我似乎无法摆脱它。如果用户按键或移动啮齿动物(又名鼠标),我想终止应用程序。这是我的代码(不要笑!)


您可以使用break语句退出循环

编辑:好的,我收回国旗的东西

您的“忙碌等待”策略设计不佳。相反,您应该使用触发的事件处理程序:

  • 按键盘
  • 当鼠标移动时

在这两种情况下,您都可以通过终止应用程序来响应。

关键字将终止循环。在本例中,当您点击要停止循环的案例时,您只需使用
break

按键事件处理程序需要将bgNotClicked变量设置为false

如果啮齿动物被鼠标移动,则需要类似的鼠标事件处理程序

Exit While

这似乎不是正确的方法。Net Framework为您提供了处理按键和鼠标移动/单击操作的事件。为什么不使用它们?

编辑:

看到你的编辑后,这肯定是你的问题。问题是while循环阻塞了主UI线程,因此它从不处理触发按键/鼠标/etc处理程序的Windows消息

您有两个选择—您可以将其中的一部分移动到单独的线程上,执行我在下面建议的操作,或者在while循环中添加对的调用。这将允许您的事件处理程序运行,从而将
bgNotClicked=false。现在,这永远不会发生,因为您的UI被完全阻止


原职:

如果在UI线程中执行此循环,则需要重新考虑一下设计

设置
bgNotClicked=false
事件处理程序中的某个位置将起作用,但前提是事件处理程序能够运行。如果您在UI线程中执行上述代码,它将无限期地阻止UI线程,从而阻止事件处理程序触发


我建议对其进行修改,使其基于计时器(因此它会定期重复运行),而不是锁定在while循环中。这将允许在运行之间触发其他UI事件,而不是设置
bgNotClicked=false,事件处理程序只能将计时器设置为未启用。

尝试将循环移动到BackgroundWorker的DoWork事件处理程序中。然后您的GUI仍然会有响应,而不是那个讨厌的变量,您可以调用CancelAsync方法来停止循环。

如果您像这样循环,您需要给应用程序一点时间来处理您希望会导致中断的事件。这是DoEvents方法的工作

private bool WeAreDone = false;

private void DoingIt()
{
    while (true)
    {
        Application.DoEvents();
        if (WeAreDone)
        {
            break;
        }
    }
}

private void InterruptButton_Click(object sender, EventArgs e)
{
    WeAreDone = true;
}

我认为使用计时器比繁忙的等待-等待-等待循环更适合Windows事件驱动模式。您可以尝试以下方法:

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

    private int iCounter = 0;

    private void Draw()
    {
        // ....
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Draw();

        iCounter++;
        if(iCounter == 399)
        {
            iCounter = 0;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Interval = 5;
        timer1.Enabled = true;
    }

    private void Form1_Click(object sender, EventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }
}

使用
环境。退出(2)
(或
环境。退出(1)
这真的没有什么区别)退出应用程序。

我想我会从现在开始一直称它为“啮齿动物”。天哪,我刚刚意识到啮齿动物就是老鼠。太棒了。@Peter:我更新了我的答案以回应你的编辑。问题是你的UI消息泵被阻止了,所以你的处理程序永远不会运行。到底为什么需要全局性的标记呢?读这个答案伤害了我的感情(全球任何事情(包括单例和静态类)都让我非常难过。如果一只啮齿动物在你不看的时候出现在你的桌子上并移动你的啮齿动物呢?当一只啮齿动物陷入连续循环时,这说起来容易做起来难。非常感谢!Application.DoEvents();成功了。干得好。@Reed Copsey:在你的编辑中--嘿!我是这么说的!大约十分钟后。干得好。@Peter:不过我建议你在结尾时改用我提到的计时器方法-这将是一个更干净的设计,更符合标准的windows窗体事件模型。DoEvents可能会有副作用,例如t次,这是不可取的。看起来他的代码直接与UI接口。在后台工作程序上运行没有帮助。除非他将其放入ProgressChanged事件中。我认为他的while循环位于paint消息处理程序中(基于其中包含e.Graphics),因此计时器可以调用Invalidate(),并让绘制处理程序处理其余部分。
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private int iCounter = 0;

    private void Draw()
    {
        // ....
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Draw();

        iCounter++;
        if(iCounter == 399)
        {
            iCounter = 0;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Interval = 5;
        timer1.Enabled = true;
    }

    private void Form1_Click(object sender, EventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }
}