我在我的表单上添加了这样的加载消息:
public void myFunc()
{
lbl_status.Text = "Loading ... Please Wait";
// Some Database Works
lbl_status.Text = "Done";
}
但是有问题。有时当我点击按钮(myFunc
方法)时,我的应用程序不会显示正在加载的消息。它只是在数据库工作,而不是显示完成消息。
我知道有时数据库的工作速度非常快,所以加载消息不会显示,但有时它不会那么快,就像我第一次打开我的应用程序一样。那时我的应用程序似乎被禁用,没有按钮,没有textBoxes和...工作,在数据库工作后,它将是正常的,显示完成消息,永远不再显示正在加载消息!
答案 0 :(得分:3)
您可以在后台线程中执行数据库工作:
public void myFunc()
{
lbl_status.Text = "Loading ... Please Wait";
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
编辑:oops DB工作应该在DoWork事件处理程序中:)
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// Some Database Works
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lbl_status.Text = "Done";
}
答案 1 :(得分:2)
您的应用程序与所有Windows GUI应用程序一样,需要处理GUI事件。正是这些事件做了一些事情,比如刷新标签并使你的应用程序看起来“响应”。见Window Messages。当您致电Application.Run
时,您的winforms应用程序会运行消息循环:
开始在当前线程上运行标准的应用程序消息循环
如果您在等待数据库工作时阻止处理,那么它将停止刷新并且它将无响应(不响应点击或键盘)。所以你必须用你的数据库来阻止主循环。有几种选择:
BackgroundWorker
。ThreadPool.QueueUserWorkItem
。SqlCommand.BeginExecuteReader
和完成回调SqlCommand.ExecuteReaderAsync
每种方法都有利有弊,最容易入手的可能是第一种方法。请注意,从后台线程或完成回调中,必须在与主GUI交互时使用Control.Invoke
(即更新表单或其上的任何元素时)。
答案 2 :(得分:1)
必须在UI线程上对UI对象进行任何更新。
您应该查看Control.Invoke,以便为调用Control所在的Display线程提供一种方法。
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke%28v=vs.110%29.aspx
为了进一步说明,这也意味着您应该在后台线程上进行大量更新。
WorkerThread可能是一个很好的解决方案。