Reputation: 759
I am working with Background Worker but neither i am able to synchronize my progress bar nor able to stop or abort the process.
in my dowork function
void bw_DoWork(object sender, DoWorkEventArgs e)
{
if(bw.CancellationPending==true)
{
e.cancel=true;
return;
}
else
{
e.Result = abc();
}
}
int abc()
{
//my work
Count++;
return count;
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(bw.CancellationPending==true)
{
button17.Visibility = Visibility.Visible;
label1.Content = "Aborted";
}
button17.Visibility = Visibility.Visible;
label1.Content = "Completed";
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
if(bw.IsBusy)
{
bw.CancelAsync();
}
}
Now i want to know how could i Synchronize my Progress Bar and how to exit from the process?
Upvotes: 3
Views: 1515
Reputation: 23300
(You might want to check out this other SO question/answer for details about the new async
facility! It greatly improves the quality of life of developing this kind of operations!)
BackgroundWorker is event-based, basic usage is the following (the link provides many useful additional details):
var worker = new BackgroundWorker();
// The following two props must be true:
// #1: The worker will be enabled to signal its progress
worker.WorkerReportsProgress = true;
// #2: The worker will accept cancellation
worker.WorkerSupportsCancellation = true;
// Now the events:
worker.DoWork += (s,e) =>
{
int i = 0; // This goes from 0 to 100
// Do code, update 'i'
worker.ReportProgress(i);
worker.CancelAsync(); //... to cancel the worker if needed
// WARNING: This code *cannot* interact with the UI because
// it's running in a different thread
};
worker.ProgressChanged += (s,e)=>
{
// This is executed when you call ReportProgress() from DoWork() handler
// IMPORTANT: All UI interaction **must** happen here
// e.ProgressPercentage gives you the value of the parameter you passed to
// ReportProgress() (this mechanism is a perfect fit for a progress bar!)
};
worker.RunWorkerCompleted+= (s,e) =>
{
// code here runs when DoWork() is done, is canceled or throws.
// To check what happened, the link provides this sample code:
if (e.Cancelled == true)
{
// Cancelled!
}
else if (e.Error != null)
{
// Exception !
}
else
{
// Work completed!
}
};
worker.RunWorkerAsync();
It's important to know that (extracted from the link above):
You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.
UPDATE Lambdas here are used to keep code compact. You can obviously use "normal" handlers or whatever other method of attaching code to events you like/want/need.
Upvotes: 0
Reputation: 14334
This is a rubbish and trivial answer but give the Task Parallel library a whirl. http://msdn.microsoft.com/en-us/library/dd537608.aspx
This library encapsulates threads as discrete Task objects. It supports cancellation.
Be warned that in a worker thread, pause and cancellation operation have to be supported by the worker code itself, by polling pause/cancel flags and tokens. You cannot safely achieve these operations with threads alone.
It is a nicer pattern to work with
As for your question, 2 flags are required to support your operations. You will be need to check them at intervals during the worker code.
bool pause = false;
bool cancel = false;
void DoWork()
{
try
{
...
//periodically check the flags
if(cancel) return;
while(paused){}; //spin on pause
...
}
finally
{
//cleanup operation
}
}
Alastair Pitts' answer illustrates how background worker supports these features. So does MSDN ;) http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx
Upvotes: 0
Reputation: 19601
Have you set the BackgroundWorker.WorkerReportsProgress && BackgroundWorker.WorkerSupportsCancellation properties on your instance to be true
?
e.g.
var myBackgroundWorker = new BackgroundWorker();
myBackgroundWorker.WorkerReportsProgress = true;
myBackgroundWorker.WorkerSupportsCancellation = true;
//the rest of the init
If you want to report progress, you need to call the BackgroundWorker.ReportProgress() method from inside your DoWork
.
Upvotes: 1