问题
I want to display a "loading form" (a form with some text message plus a progressBar with style set to marquee) while the BackgroundWorker's job isn't done. When the BackgroundWorker is done, the loading form must be closed automatically. Although I do use a BackgroundWorker, the main thread should wait until it's done. I was able to do that using a AutoResetEvent but I noticied that as it does block the main thread, the form loading's progressBar is freezed too.
My question is: How can I show that form without freeze it while runing a process in background and wait for it finish? I hope it's clear.
Here's my current code:
BackgroundWorker bw = new BackgroundWorker();
AutoResetEvent resetEvent = new AutoResetEvent(false);
//a windows form with a progressBar and a label
loadingOperation loadingForm = new loadingOperation(statusMsg);
//that form has a progressBar that's freezed. I want to make
// it not freezed.
loadingForm.Show();
bw.DoWork += (sender, e) =>
{
try
{
if (!e.Cancel)
{
//do something
}
}
finally
{
resetEvent.Set();
}
};
bw.RunWorkerAsync();
resetEvent.WaitOne();
loadingForm.Close();
MessageBox.Show("we are done!");
回答1:
Connect your BackgroundWorker's RunWorkerCompleted to a callback that will close the form like so:
private void backgroundWorker1_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
loadingForm.Close();
MessageBox.Show("we are done!");
}
You can delete the resetEvent.WaitOne();
You'll need to make loadingForm a field of course.
Tell me more
Occurs when the background operation has completed, has been canceled, or has raised an exception
- BackgroundWorker.RunWorkerCompleted
回答2:
Make the login form object an instance variable.
//use RunWorkerCompleted event to get notified about work completion where you close the form.
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
event handler code:
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.loadingForm.close();
}
Reference: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted(v=vs.110).aspx
回答3:
Cek this script, Loading is Form with PictureBox - image gif
private delegate void showProgressCallBack(int value);
private void btnStart5_Click(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
Loading f = new Loading();
f.Show();
bw.DoWork += (s, ea) =>
{
try
{
test1();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
};
bw.RunWorkerCompleted += (s, ea) =>
{
f.Close();
};
bw.RunWorkerAsync();
}
private void showProgress(int value)
{
if (progressBar1.InvokeRequired)
{
showProgressCallBack showProgressDelegate = new showProgressCallBack(showProgress);
this.Invoke(showProgressDelegate, new object[] {value});
}
else
{
progressBar1.Value = value;
}
}
private void test()
{
showProgress(20);
Thread.Sleep(3000);
showProgress(80);
Thread.Sleep(2000);
showProgress(100);
}
来源:https://stackoverflow.com/questions/29382305/show-a-form-while-backgroundworker-is-running