我正在尝试做一个加载表单。所以我放了一个动画 gif 来做加载效果。
发生的情况是,当我使用loading.Visible = true
属性时,在单击事件结束之前,这是不可见的。
这是代码。
Private void btnLogin_Click (object sender, EventArgs e)
{
loading.Visible = true;
if (ConnectDataBase())
{
OpenForm2();
This.Close();
}
else MessageBox.Show ("User or password, incorrect");
loading.Visible = false;
}
数据库在ConnectDataBase()
函数中需要 3 到 6 秒才能响应,但在事件结束之前,gif 不会变得可见。
有人可以告诉我,我该怎么做?
您需要在后台运行数据库连接。有很多方法可以做到这一点,但随着async/await
的出现,这将是最简单的方法:
private async void btnLogin_Click (object sender, EventArgs e)
{
loading.Visible = true;
if (await Task.Run(() => ConnectDataBase()))
{
OpenForm2();
This.Close();
}
else MessageBox.Show ("User or password, incorrect");
loading.Visible = false;
}
请注意以下更改:
- 我使该方法
async void
向编译器发出我们要使用的信号async/await
我创建了一个任务来运行数据库连接:
await Task.Run(() => ConnectDataBase())
这将返回一个
bool
,ConnectDataBase()
的结果,并将 基本上与这里的另一个答案做同样的事情,只是 减少手动混乱和任务处理。
观察:通过这样的后台执行,用户可以再次单击Login
按钮,而第一次单击仍在执行(并尝试连接到数据库(。您应该采取措施确保这是不可能的,例如在执行此操作时禁用登录按钮(以及其他字段,例如用户名、密码等(,如下所示:
private async void btnLogin_Click (object sender, EventArgs e)
{
btnLogin.Enabled = eUsername.Enabled = ePassword.Enabled = false;
loading.Visible = true;
... rest of method
loading.Visible = false;
btnLogin.Enabled = eUsername.Enabled = ePassword.Enabled = true;
}
注意如果可能,最好将ConnectDataBase
方法重写为异步方法,因为现在大多数 .NET 数据库连接服务都有执行此操作的方法。在不了解此方法的作用的情况下,我只能发表一般性评论。
下面是如何编写 SQL Server 连接尝试的示例:
public static async Task<bool> ConnectDataBase()
{
var connection = new SqlConnection("connection string");
try
{
await connection.OpenAsync();
// store "connection" somewhere I assume?
return true;
}
catch (SqlException)
{
connection.Dispose();
return false;
}
}
通过此更改,您可以将原始方法中的if
-语句更改为以下内容:
if (await ConnectDataBase())
为了使它工作,您需要在不同的线程上调用 ConnectDataBase((。 一种方法是:
private void btnLogin_Click(object sender, EventArgs e)
{
loading.Visible = true;
Task.Run<bool>(() =>
{
return ConnectDataBase();
})
.ContinueWith(t =>
{
if (t.Result)
{
OpenForm2();
this.Close();
}
else MessageBox.Show("User or password, incorrect");
}, TaskScheduler.FromCurrentSynchronizationContext());
}