单击按钮从循环中断-C# [英] Breaking from a loop with button click - C#

查看:102
本文介绍了单击按钮从循环中断-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于按钮单击事件循环的问题,我已经尝试了许多方法&在过去一个小时内搜索了许多页面以寻找一个简单的答案,但事实是每个答案看起来都像是外来代码,可能是因为我对开发仍然很陌生.

I have a question regarding looping with button click event, I've tried many methods & searched many pages in search for a simple answer for the past hour, but the truth is each answer just looks like alien code, probably because I'm still very new to developing.

这是我要执行的操作的简化版本:

Here's a simplified version of what I'm trying to do :

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);
}

显然,这不是我的API,或者发明起来毫无用处,但是代码本身很长,你们总是要求相关代码"(不要无礼),所以就在那里.

Obviously this isn't my API, or it'd be a useless thing to invent, however, the code itself is long & you guys always ask for "relevant code" (No disrespect), so there it is.

我的问题:在单击按钮2时突破了垃圾邮件循环,对我来说,代码看起来不错,API可以确定,但是每次单击按钮1时,API都会冻结.

My problem : Breaking out of the spam loop upon clicking button 2, the code to me looks decent enough for the API to figure out, but each time button 1 is clicked, the API freezes.

推荐答案

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

Use a background worker to do your work. You can use the cancellation feature to break out of it when you're done. Your loop as you have it will block the UI thread when executed syncronously, which is why your GUI becomes unresponsive. Note if you do any interaction with the UI in the do work delegate, you need to marshal back onto the UI thread (via invoke for example).

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();
}

更新2019 : BackgroundWorker现在已基本过时,在更高版本的C#中由async/await功能所取代,该功能更易于使用.这是一个使用该功能如何实现相同目的的示例:

Update 2019: BackgroundWorker is now largely obsolete, replaced by the async/await feature in later versions of C# which is easier to use. Here is an example of how to achieve the same thing using that feature:

private CancellationTokenSource _canceller;

private async void goButton_Click(object sender, EventArgs e)
{
    goButton.Enabled = false;
    stopButton.Enabled = true;

    _canceller = new CancellationTokenSource();
    await Task.Run(() =>
    {
        do
        {
            Console.WriteLine("Hello, world");
            if (_canceller.Token.IsCancellationRequested)
                break;

        } while (true);
    });

    _canceller.Dispose();
    goButton.Enabled = true;
    stopButton.Enabled = false;
}

private void stopButton_Click(object sender, EventArgs e)
{
    _canceller.Cancel();
}

这篇关于单击按钮从循环中断-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆