This is really easy to using a 'BackGroundWorker Component, and a 'ProgressBar Control.
The 'BackGroundWorker gives you an easy way to run an operation asynchronously.
Since you want to "freeze" the UI, you need to use 'ShowDialog, so you will need a Form to put your ProgressBar on. In that Form we need to provide a way for an external "customer" to update the ProgressBar:
public void SetProgressBarValue(int pbValue)
{
progressBar1.Value = pbValue;
}
The BackGroundWorker exposes three main Events that you can handle:
1. DoWork: this is where you will start the Query, and this is where you must figure out how to meaningfully update the ProgressBar.
2. ProgressChanged: this Event which is, strangely, called by using the ReportProgress method of the BackGroundWorker is passed an integer value, and it is in this EventHandler you'll update the ProgressBar.
3. RunWorkerCompleted: triggered for you when the BackGroundWorker is done, and this is where you will close the Form that displays the DialogBox.
Assuming your Form with the ProgressBar is named 'ProgressBarForm, and in your main Form's code you have created an instance of it assigned to a variable named 'frmPgBar, and your BackGroundWorker Component (drag-dropped onto your main form from the ToolBox) is named 'bgwQuery
Starting the BackGroundWorker:
1. in your EventHandler for the user-interface element that now triggers the Query:
bgwQuery.RunWorkerAsync();
frmPg.ShowDialog();
Now your code in your 'DoWork EventHandler is going to be executed, and you face the challenge of figuring out how to update the ProgressBar with some meaningful value so that when you call 'ReportProgress(#integer) in your 'DoWork code:
private void bgwQuery_DoWork(object sender, DoWorkEventArgs e)
{
while (? some condition)
{
bgwQuery.ReportProgress(#integer);
}
}
In the ProgressChanged EventHandler:
private void bgwQuery_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
frmPgBar.SetProgressBarValue(e.ProgressPercentage);
}
Finally, in your RunWorkerCompleted handler, you can close the Form with the ProgressBar:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
frmPgBar.Close();
}
Note for other advanced uses of BackGroundWorker including passing parameters into the 'DoWork EventHandler, using assignment to the 'Result field of DoWork's DoWorkEventArgs to transfer data back to the main UI thread, etc., see MSDN docs.