如何使用按钮停止for循环?

Xce*_*ist 3 c# loops for-loop button

我有一个循环,我想停止使用按钮.编辑以便更好地理解:

我确实意识到在循环运行时你无法停止按钮,因为只要当前的UI正在运行它就无法工作.我真正要求的是创建线程或使用BGWorker来阻止它的最有效方法.我见过一些方法,但大部分方法都是针对Java而不是C#.

我想做的是:

private void start_Click(object sender, EventArgs e)
{

    for(int i = 0; i < nums; i++)
    {
        doSomething();
    }
}

private void stop_Click(object sender, EventArgs e)
{

    stops start_Click()
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*NET 7

你不能这样做.对于初学者来说,for循环在UI线程上同步运行,这意味着您甚至无法单击"停止"按钮.

因此,您需要将for循环的操作移动到另一个线程,这意味着您可能根本不会使用for循环.您需要考虑实际上需要如何执行代码,然后根据您执行处理的方式,您可以实现"停止"按钮.

一个非常简单的方法是:

new Thread(() =>
{
   int i = 0;
   while (!stop && i < num)
   {
      doSomething();
      i++;
   }
 }).Start();
Run Code Online (Sandbox Code Playgroud)

并设置stop为停止处理循环.在更现实的场景中,您可以排队要处理的函数,然后通过类似的方法停止出列.不幸的是,在不了解更多细节的情况下难以推荐设置.

任何基于您的代码的解决方案也会doSomething()遇到当前完成执行的问题(可能需要一段时间).再说一遍,没有更多的信息,很难说最好的方法是什么.


Sie*_*jet 5

为了使您的UI响应能够取消正在运行的操作,您可以使用背景工作者.backgroundworker在保持UI响应的同时在另一个线程中完成工作:

    private readonly BackgroundWorker _backgroundWorker;

    public Form1()
    {
        InitializeComponent();

        _backgroundWorker = new BackgroundWorker
        {
            WorkerSupportsCancellation = true
        };
        _backgroundWorker.DoWork += backgroundWorker_DoWork;
        _backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;

        Disposed += Form1_Disposed;
    }

    private void Form1_Disposed(object sender, EventArgs e)
    {
        _backgroundWorker.Dispose();
    }

    private void StartLoop()
    {
        if ( !_backgroundWorker.IsBusy )
        {
            _backgroundWorker.RunWorkerAsync();
        }
    }

    private void StopLoop()
    {
        _backgroundWorker.CancelAsync();
    }

    private void backgroundWorker_DoWork( object sender , DoWorkEventArgs e )
    {
        var backgroundWorker = ( BackgroundWorker ) sender;

        for ( var i = 0; i < 100; i++ )
        {
            if ( backgroundWorker.CancellationPending )
            {
                e.Cancel = true;
                return;
            }
            // Do Work
        }
    }

    private void backgroundWorker_RunWorkerCompleted( object sender , RunWorkerCompletedEventArgs e )
    {
        if ( e.Cancelled )
        {
            // handle cancellation
        }
        if ( e.Error != null )
        {
            // handle error
        }

        // completed without cancellation or exception
    }
Run Code Online (Sandbox Code Playgroud)