在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就可以从那里停止。
答案 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
未设置。