我正在调用一个login()方法,该方法处理与mysql服务器的连接,然后对用户进行身份验证。连接到mysql服务器需要一些时间,所以我想放置一个显示“正在加载”状态的标签。我正在做这样的事情:
private void button_login_Click(object sender, EventArgs e)
{
label_status.Text = "Loading ...";
login();
}
但是我没有看到label_status文本更改为“正在加载...”。相反,它会在登录函数返回后在label_status中显示此状态。
我不知道为什么会这样?这是一些线程问题吗?任何帮助,将不胜感激。
答案 0 :(得分:4)
UI线程将在事件处理程序的持续时间内被阻止。如果您希望能够更新UI,则需要在非UI线程中执行长时间运行的任务。 BackgroundWorker
专为此而设计。 Here是关于如何使用它的教程。
您应该在开始BackgroundWorker
之前设置文本,将DoWork
方法设置为执行login
,如果您在登录后需要进行任何UI更新,则可以调用他们在Completed
事件中。
对于不需要完整BGW解决方案的小型案例,您可以使用任务并行库,因为它允许更简单的案例保持简单。以下是使用TPL的标准模型:
private void button1_Click(object sender, EventArgs e)
{
//UpdateUI with stuff to do before long running task
Task.Factory.StartNew(() => someLongRunningNonUITask())
.ContinueWith(task => updateUIWithResults(task)
, TaskScheduler.FromCurrentSynchronizationContext());
}
答案 1 :(得分:1)
快速而肮脏的方法是在更改文本之后和调用login()方法之前调用Application.DoEvents()。这将导致标签在调用login()方法之前重新绘制。
private void button_login_Click(object sender, EventArgs e)
{
label_status.Text = "Loading ...";
Application.DoEvents();
login();
}