I’m trying to create a ProgressBar form that uses a BackgroundWorker to execute an action on a different thread while displaying a progress bar.
At the moment my ProgressBar class contains a ProgressBarControl and here’s how the code looks like:
public partial class QTProgressBar : DevExpress.XtraEditors.XtraForm
{
private BackgroundWorker m_backgroundWorker;
private AutoResetEvent m_resetEvent;
public QTProgressBar()
{
InitializeComponent();
InitializeProgressBar();
m_backgroundWorker = new BackgroundWorker();
m_backgroundWorker.WorkerReportsProgress = true;
m_backgroundWorker.WorkerSupportsCancellation = true;
m_backgroundWorker.DoWork += new DoWorkEventHandler(m_backgroundWorker_DoWork);
m_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(m_backgroundWorker_ProgressChanged);
m_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_backgroundWorker_RunWorkerCompleted);
m_resetEvent = new AutoResetEvent(false);
}
void m_backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
m_resetEvent.Reset();
CloseProgressBar();
}
void CloseProgressBar()
{
if (InvokeRequired)
{
Invoke( new MethodInvoker(CloseProgressBar));
return;
}
this.Close();
}
void m_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Action operation = e.Argument as Action;
operation();
}
public void StartAsyncTask(Action operation)
{
m_resetEvent.Set();
m_backgroundWorker.RunWorkerAsync(operation);
}
}
For now, when i want to show a popup i do this:
QTProgressBar op = new QTProgressBar();
op.StartAsyncTask(() => LongDurationOperation(5, 5));
op.ShowDialog(); // i would like to move this inside the ProgressBar class.
//Thread gets blocked here until operation finishes.
Where LongDurationOperation is :
public void LongDurationOperation(int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Thread.Sleep(100);
}
}
}
I would like to avoid blocking any thread that calls the
ShowDialog()
method of the progressBar class.
If i move this anywhere inside the ProgressBar class thread gets blocked and operation does not execute.
Is it possbile to avoid blocking the thread that calls the Showdialog() method?
Also, can you give me some hints on how this class can be improved?
Thanks a lot.
There is two different call that exist in a form:
Is the modal version that block the thread calling it. It is used for popup that must prevent other action from taking place (like save dialog).
Is the non-modal version. It doesn’t block the current thread, but doesn’t return any result. However, you must pass it the owner, often like this: