单击按钮从循环中断 - C#

Hel*_*123 13 c# loops button

我有一个关于循环按钮点击事件的问题,我尝试了很多方法并搜索了许多页面以寻找过去一小时的简单答案,但事实是每个答案看起来都像外星人的代码,可能是因为我还在发展的新手.

这是我正在尝试做的简化版本:

private string Message = "Hello";

private void Spam(bool loop)
{
    if (loop == true)
    {
        while (loop == true)
        {
            MessageBox.Show(Message);
        }
    }
    else { MessageBox.Show("Spamming has stopped !! "); }
}

private void button1_Click(object sender, EventArgs e)
{
    Spam(true);
}
private void button2_Click(object sender, EventArgs e)
{
    Spam(false);
}
Run Code Online (Sandbox Code Playgroud)

显然这不是我的API,或者它是一个无用的东西发明,但是,代码本身很长并且你们总是要求"相关代码"(没有不尊重),所以就是这样.

我的问题:单击按钮2时打破垃圾邮件循环,我的代码看起来足够让API可以搞清楚,但每次点击按钮1时,API都会冻结.

ste*_*351 14

使用后台工作人员来完成您的工作.完成后,您可以使用取消功能打破它.您拥有它的循环将在同步执行时阻止UI线程,这就是您的GUI变得无法响应的原因.请注意,如果您与do work委托中的UI进行任何交互,则需要封送回UI线程(例如,通过调用).

private BackgroundWorker _worker = null;

private void goButton_Click(object sender, EventArgs e)
{
    _worker = new BackgroundWorker();
    _worker.WorkerSupportsCancellation = true;

    _worker.DoWork += new DoWorkEventHandler((state, args) =>
    {
        do
        {
            if (_worker.CancellationPending)                
                break;

            Console.WriteLine("Hello, world");

        } while (true);
    });

    _worker.RunWorkerAsync();
    goButton.Enabled = false;
    stopButton.Enabled = true;
}

private void stopButton_Click(object sender, EventArgs e)
{
    stopButton.Enabled = false;
    goButton.Enabled = true;
    _worker.CancelAsync();
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,并且很好地介绍了后台工作人员。你让我过得很愉快。 (2认同)

Hei*_*nzi 7

要记住一件重要的事情:

在执行代码时,用户无法与您的用户界面进行交互.

这意味着:您首先需要退出循环(即从Spam方法返回),然后用户可以单击Button2.

这是一个很难的事实,因为这意味着你无法以你想要的方式编写代码.幸运的是,有几种方法可以解决这个问题:

  • 不要使用循环.使用某种计时器来做"垃圾邮件".Button1启动计时器,Button2停止计时器.什么样的计时器可用取决于您使用的用户界面库(WinForms有一个Timer,WPF有一个DispatcherTimer).

  • 后台线程中进行"垃圾邮件" .这将允许您的用户界面保持响应,并且您可以与后台线程进行通信,例如,通过设置a volatile Boolean.但是,这是一个高级主题(并且可能很快导致复杂的同步问题),因此我建议您先尝试其他选项.