I've got one form called Sorter. There is the button 'jademy' on it which opens window 'Progress Window'
private void jademy_Click(object sender, EventArgs e)
{
ProgressWindow progress = new ProgressWindow();
progress.ShowDialog();
}
Code of 'Progress Window' form is following:
public partial class ProgressWindow : Form
{
private BackgroundWorker backgroundWorker = new BackgroundWorker();
public ProgressWindow()
{
InitializeComponent();
stop.Visible = true;
ok.Visible = false;
backgroundWorker.RunWorkerAsync();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
#region block1
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
#endregion
}
private void stop_Click(object sender, EventArgs e)
{
backgroundWorker.CancelAsync();
}
private void ok_Click(object sender, EventArgs e)
{
this.Close();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100);
backgroundWorker.ReportProgress(i);
}
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
this.Text = "Done: " + e.ProgressPercentage.ToString() + "%";
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
MessageBox.Show("Cancelled", "Message", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
}
else if (!(e.Error == null))
{
MessageBox.Show("Error: " + e.Error.Message, "ERROR!", MessageBoxButtons.OKCancel);
}
else
{
ok.Visible = true;
stop.Visible = false;
}
}
}
Now. I have three problems.
Click on stop button does nothing. It seems that 'backgroundWorker.CancelAsync()' doesn't stop the process.
When I close progress window and I want to run it again I have to wait some time before click on 'jademy' button. Otherwise progress window is displayed like this:
(and nothing changes) instead of this:
It looks like the program "remembers" that work was done even though it is a new instance of ProgressWindow. Notice that on the incorrect version 'OK' button is visible at once - instead of waiting for the completion of the work.
I would like to clarify the code in "block 1". To be honest I don't understand it fully. Is this part really essential or not? I mean, I've found a lot of examples (also on this forum - e.g. here), where this part wasn't included and users were reporting that the solution works. In my case, without this part progress bar didn't work at all, but maybe I've done something wrong.
CancelAsync submits a request to terminate the pending background operation and sets the CancellationPending property to true.
When you call CancelAsync, your worker method has an opportunity to stop its execution and exit. The worker code should periodically check the CancellationPending property to see if it has been set to true.
BackgroundWorker.CancelAsync is often misunderstood. It does not stop any pending work but is merely a signal to the UI thread that the work has been canceled! It just sets the CancellationPending property, which you can poll in the DoWork regularly.
Unfortunately the MSDN example with the Thread.Sleep calls in the DoWork is a very silly one. Normally you call a blocking operation in DoWork, which is often completely UI-independent.
See my answer here for a more usable example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With