如何在后台工作中暂停/恢复循环?

时间:2016-06-18 03:10:45

标签: c# .net winforms

在form1的顶部

private System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(false);
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();

启动backgroundworker和计时器的按钮单击事件

private void startButton_Click(object sender, EventArgs e)
        {
            startButton.Enabled = false;
            stopButton.Enabled = true;
            timer1.Start();
            if (!backgroundWorker1.IsBusy)
                backgroundWorker1.RunWorkerAsync();
        }

Dowork活动

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            _stopwatch.Restart();
            DirSearch(@"d:\c-sharp", "*.cs", "Form1", worker, e);
            _stopwatch.Stop();
        }

DirSearch方法

private void DirSearch(string root, string filesExtension,string textToSearch, BackgroundWorker worker, DoWorkEventArgs e)
        {
            int numberoffiles = 0;
            int numberofdirs = 0;
            string[] filePaths = Directory.GetFiles(root, filesExtension, SearchOption.AllDirectories);
            for (int i = 0; i < filePaths.Length; i++)
            {
                _busy.WaitOne();
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    return;
                }

                List<MyProgress> prog = new List<MyProgress>();
                int var = File.ReadAllText(filePaths[i]).Contains(textToSearch) ? 1 : 0;
                if (var == 1)
                {
                    string filename = filePaths[i];
                    numberoffiles ++;
                    prog.Add(new MyProgress { Report1 = filename, Report2 = numberoffiles.ToString() });
                    backgroundWorker1.ReportProgress(0, prog);
                    Thread.Sleep(100);
                }
                numberofdirs ++;
                label1.Invoke((MethodInvoker)delegate
                            {
                                label1.Text = numberofdirs.ToString();
                                label1.Visible = true;
                            });
            }
        }

暂停/恢复的按钮点击事件

private void pauseresumeButton_Click(object sender, EventArgs e)
        {
            if (pauseresumeButton.Text == "Resume")
            {
                pauseresumeButton.Text = "Pause";
                _busy.Set();
            }
            else
            {
                pauseresumeButton.Text = "Resume";
                _busy.Reset();
            }
        }

设计师中的pauseresumeButton文本设置为&#34;暂停&#34;

问题是DirSearch中的_busy.WaitOne();使得当我点击开始按钮时,只有计时器正在运行。然后我需要点击pauseresumeButton来启动它,就像恢复它一样。

我想要做的是当我点击开始按钮时,所有内容都将启动计时器和DirSearch。然后,如果我点击pauseresumeButton来暂停后台工作者的计时器和DirSearch操作,再点击pauseresumeButton就可以从那里停止。

1 个答案:

答案 0 :(得分:2)

由于启动worker类似于恢复,因此可以将公共部分移动到单独的方法:

private void SetWorkerMode(bool running)
{
    if (running)
    {
        pauseresumeButton.Text = "Pause";
        _busy.Set();
    }
    else
    {
        pauseresumeButton.Text = "Resume";
        _busy.Reset();
    }
}

然后从两个地方使用它:

private void startButton_Click(object sender, EventArgs e)
{
    // ...
    if (!backgroundWorker1.IsBusy)
    {
        SetWorkerMode(true);
        backgroundWorker1.RunWorkerAsync();
    }
}

private void pauseresumeButton_Click(object sender, EventArgs e)
{
    SetWorkerMode(pauseresumeButton.Text == "Resume");
}

我想您现在可以看到当前代码的问题 - pauseresumeButton显示“暂停”,但_busy未设置。