在方法执行代码时显示进度表单的最佳方式
本文关键字:表单 最佳 方式 显示 方法 执行 代码 | 更新日期: 2023-09-27 18:07:10
我有一个WinForm加载方法,它需要很长时间才能收集一些数据显示给用户。
当这个方法执行时,我显示了一个带有"Loading"字样的大字体表单。
然而,有时这个错误出现,"加载"进度表单不关闭,然后最终我的整个应用程序将退出:
创建窗口句柄错误。在System.Windows.Forms.NativeWindow。CreateHandle (CreateParams cp)
是否有更好的方法来显示我的进度/加载表单,而我在加载方法中执行代码?
这是我的代码:
//I launch a thread here so that way the Progress_form will display to the user
//while the Load method is still executing code. I can not use .ShowDialog here
//or it will block.
//Progress_form displays the "Loading" form
Thread t = new Thread(new ThreadStart(Progress_form));
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.IsBackground = true;
t.Start();
//This is where all the code is that gets the data from the database. This could
//take upwards of 20+ seconds.
//Now I want to close the form because I am at the end of the Load Method
try
{
//abort the Progress_form thread (close the form)
t.Abort();
//t.Interrupt();
}
catch (Exception)
{
}
BackgroundWorker
是在不锁定UI线程的情况下执行长时间运行操作的好方法。
使用下面的代码来启动一个BackgroundWorker并显示一个正在加载的表单。
// Configure a BackgroundWorker to perform your long running operation.
BackgroundWorker bg = new BackgroundWorker()
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
// Start the worker.
bg.RunWorkerAsync();
// Display the loading form.
loadingForm = new loadingForm();
loadingForm.ShowDialog();
这将导致以下方法在后台线程中执行。注意,您不能从这个线程操作UI。尝试这样做将导致异常。
private void bg_DoWork(object sender, DoWorkEventArgs e)
{
// Perform your long running operation here.
// If you need to pass results on to the next
// stage you can do so by assigning a value
// to e.Result.
}
当长时间运行的操作完成时,这个方法将在UI线程上被调用。现在您可以安全地更新任何UI控件。在您的示例中,您想要关闭加载表单。
private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Retrieve the result pass from bg_DoWork() if any.
// Note, you may need to cast it to the desired data type.
object result = e.Result;
// Close the loading form.
loadingForm.Close();
// Update any other UI controls that may need to be updated.
}
我已经在。net 4.0上成功地测试过了。(WinForms)我有理由相信这将在。net 4.0+上工作,并且应该是一个有用的代码片段,可以在大多数需要在流程结束时关闭表单的项目中重用。
private void SomeFormObject_Click(object sender, EventArgs e)
{
myWait = new YourProgressForm();//YourProgressForm is a WinForm Object
myProcess = new Thread(doStuffOnThread);
myProcess.Start();
myWait.ShowDialog(this);
}
private void doStuffOnThread()
{
try
{
//....
//What ever process you want to do here ....
//....
if (myWait.InvokeRequired) {
myWait.BeginInvoke( (MethodInvoker) delegate() { closeWaitForm(); } );
}
else
{
myWait.Close();//Fault tolerance this code should never be executed
}
}
catch(Exception ex) {
string exc = ex.Message;//Fault tolerance this code should never be executed
}
}
private void closeWaitForm() {
myWait.Close();
MessageBox.Show("Your Process Is Complete");
}
我会采取代码,你在你的加载方法,并将其放入一个线程。在表单的某个地方设置一个进度条,并在收集数据的代码的关键阶段增加它-小心不要在线程本身中这样做,但也就是说,不要在单独的线程中篡改ui元素,你需要使用委托来调用它们。