Reputation: 235
In the top of form1
private System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(false);
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
A button click event that start the backgroundworker and the timer
private void startButton_Click(object sender, EventArgs e)
{
startButton.Enabled = false;
stopButton.Enabled = true;
timer1.Start();
if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
}
Dowork event
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 method
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;
});
}
}
Button click event for pause/resume
private void pauseresumeButton_Click(object sender, EventArgs e)
{
if (pauseresumeButton.Text == "Resume")
{
pauseresumeButton.Text = "Pause";
_busy.Set();
}
else
{
pauseresumeButton.Text = "Resume";
_busy.Reset();
}
}
The pauseresumeButton text in designer is set to "Pause"
And the problem is that the _busy.WaitOne();
inside the DirSearch make it that when i click the start button only the timer is running. Then i need to click the pauseresumeButton to start it like resume it.
What i want to do is when i click the start button everything will start the timer and the DirSearch. And then if i click on the pauseresumeButton to pause the backgroundworker the timer and the DirSearch operation and another click on pauseresumeButton to resume from where it all stopped.
Upvotes: 0
Views: 2382
Reputation: 205849
Since starting the worker is similar to resuming, you can move the common part to a separate method:
private void SetWorkerMode(bool running)
{
if (running)
{
pauseresumeButton.Text = "Pause";
_busy.Set();
}
else
{
pauseresumeButton.Text = "Resume";
_busy.Reset();
}
}
and then use it from both places:
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");
}
I guess now you can see what's the issue with your current code - the pauseresumeButton
is showing "Pause", but the _busy
is not set.
Upvotes: 2