Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# BackgroundWorker
Dear Experts.
 
In my c# windows application, i have two buttons(export and cancel).
 
In export button i am starting one background worker-it will export database table data to the .csv file.
 
When ever the user clicks cancel button, I am displaying the message box("cancel the operation, do you want to proceed click yes") with yes or no options.
 
Here my requirement is when the when the message box appears i want to Pause the backgroundworker.
 
If user clicks yes i want to cancel the mackgroundworker(this is working).
If user clicks no i want to resume the backgrouondworker.
 
Kindly share your solutions.
Posted 6-Nov-12 17:13pm
Edited 6-Nov-12 17:40pm
v2
Comments
Philippe Mori at 6-Nov-12 23:18pm
   
Not really a solution... but I would either not display any confirmation at all (for relatively short processing) or let processing continue anyway (long processing).
 
A background worker is not designed for that and there is always a risk that you try to cancel just before the end of processing (too late to be cancelled) and a message might be displayed even though processing is completed.
 
In some cases like an exportation, it does not matters much if you continue the exportation. If the user cancel it, you should typically erase the file anyway.
Member 10380571 at 5-Nov-13 2:00am
   
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Text;
using System.Windows.Forms;
 
namespace BackgroundWorkerSample
{
public partial class Form1 : Form
{

BackgroundWorker m_oWorker;

private ManualResetEvent locker = new ManualResetEvent(true);
 
public Form1()
{
InitializeComponent();
m_oWorker = new BackgroundWorker();
m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
m_oWorker.WorkerReportsProgress = true;
m_oWorker.WorkerSupportsCancellation = true;
 

}

void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//If it was cancelled midway
if (e.Cancelled)
{
lblStatus.Text = "Task Cancelled.";
}
else if (e.Error != null)
{
lblStatus.Text = "Error while performing background operation.";
}

else
{
//lblStatus.Text = "Task Completed...";
this.BeginInvoke((MethodInvoker)delegate
{
lblStatus.Text = "Done";
button1.Enabled = false;


});


 
}
btnStartAsyncOperation.Enabled = true;
btnCancel.Enabled = false;


}
 

void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Here you play with the main UI thread
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}
 

void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
{


for (int i = 0; i < 100; i++)
{


locker.WaitOne();
Thread.Sleep(100);
m_oWorker.ReportProgress(i);
 

if (m_oWorker.CancellationPending)
{
e.Cancel = true;
m_oWorker.ReportProgress(0);
return;
}
 



}

//Report 100% completion on operation completed
m_oWorker.ReportProgress(100);
}
 

private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{
btnStartAsyncOperation.Enabled = false;
btnCancel.Enabled = true;
button1.Enabled = true;
//Start the async operation here
m_oWorker.RunWorkerAsync();
}
 
private void btnCancel_Click(object sender, EventArgs e)
{
if (m_oWorker.IsBusy)
{
//Stop/Cancel the async operation here
m_oWorker.CancelAsync();
}
}
 
private void Form1_Load(object sender, EventArgs e)
{
 
}
 
private void button1_Click(object sender, EventArgs e)
{

if (button1.Text == "PAUSE")
{
locker.Reset();
button1.Text = "RESUME";
}
else
{
locker.Set();
button1.Text = "PAUSE";
}
}


}
}
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Not background worker, a thread, any thread.
 
Well, Pause and Resume were deprecated as unsafe. Basically, a thread can get a thread synchronization object and get paused before releasing it. It can easily jam the whole process or some threads of it until the process is terminated by some external process — the jammed process might not be able to terminate itself if some non-background threads are handing.
 
The safe implementation is similar behavior can be done using thread synchronization primitives EventWaitHandle and classes derived from it. Please see:
http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx[^].
 
In certain points, the thread should call the method WaitOne() of some instance of this class. If the instance is in the wait state (reset), the calling thread will be switched of my OP and put in a wait (sleeping) state where it does not spend any CPU time. It won't be scheduled back to execution until it is waken up. It can be waken up by several events, such as Thread.Abort, timeout (if any), or, importantly, when some other thread signals the same instance of EventWaitHandle, put it to signaled state (set). So, controlling the instance of EventWaitHandle, some thread can throttle execution of some other thread, effectively implementing something similar to Pause/Resume, but in some fixed point of the code running by the thread.
 
Even if the thread is "paused" this way after it got ownership of some other event synchronization primitive object, if can always be aborted (see above), even if the instance of EventWaitHandle holding the thread is kept non-signaled (reset).
 
Now, about cancellation of the thread. Thread.Abort is the asynchronous method of thread termination, which many consider as unsafe (but this is important method which has not been deprecated). Indeed, you need to know perfectly well what are you doing, if you need to use it. Its mechanism is relatively new and extremely clever, based on the mechanism of exception seeding. Maybe this is not a place to discuss it here. Please see my past answers:
Close correcly the thread inside a dll[^],
Problem with creating Process from dedicated thread[^].
 
For cooperative thread cancellation, please see this Microsoft article:
http://msdn.microsoft.com/en-us/library/dd997364.aspx[^].
 
—SA
  Permalink  
v5
Comments
D-Kishore at 6-Nov-12 23:24pm
   
Hi Sergey, i understood what you are saying.
But i am confused, how should i proceed in my requirement.
Sergey Alexandrovich Kryukov at 6-Nov-12 23:50pm
   
Strange question. By doing some work, of course :-).
You see, I would have an idea how you can proceed only if you explain what you can already do and what not, what did you understand and what not. Your "I'm confused" is not informative...
 
I think I gave you everything you need with a lot of detail. Are you sure you are qualified enough to read it all and understand? If not, you should step back and learn more programming on more basic levels...
--SA
D-Kishore at 7-Nov-12 0:57am
   
ok
Sergey Alexandrovich Kryukov at 7-Nov-12 1:17am
   
??
D-Kishore at 7-Nov-12 2:09am
   
i am checking your links in detail
Sergey Alexandrovich Kryukov at 7-Nov-12 2:27am
   
Good idea... :-)
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

lets say your thread method have a loop in wicth you are coding the data transfer from DB to File, you have to add a condtion in there to put your thread on hold.
here is an exemple!
 

 
 
//class level declaration!
public AutoResetEvent autoRest = new AutoResetEvent(false);
bool stopThread = false;
 

your thread method
Loop
{
//transfer data from Db to .CSV 
//one line at a time or block at a time

if(stopThread == true)
   autoRest.WaitOne(); 
 
}
 
so if you put your stopThread to true, your thread will change status from runing to waitSleepJoin. it will continue its work if you call in another thread:
 
autoRest.Set();
 
there are many other ways to put your thread on hold,
Hope it helps.
  Permalink  
Comments
Nelek at 5-Nov-13 11:25am
   
Did you realize that it is a one year old question?
Ziee-M at 6-Nov-13 1:20am
   
nope, :D but it dosent matter, it may be useful for someone else!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 390
1 Sergey Alexandrovich Kryukov 329
2 Afzaal Ahmad Zeeshan 244
3 BillWoodruff 210
4 Maciej Los 192
0 OriginalGriff 5,560
1 DamithSL 4,476
2 Maciej Los 3,942
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,175


Advertise | Privacy | Mobile
Web03 | 2.8.141216.1 | Last Updated 5 Nov 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100