通过单击按钮打破循环 - C# [英] Breaking from a loop with button click - C#

查看:17
本文介绍了通过单击按钮打破循环 - 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 现在基本上已经过时,取而代之的是 async/await 在更高版本的 C# 中更易于使用的功能.以下是如何使用该功能实现相同目标的示例:

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天全站免登陆