如何管理加载动画线程? - C#



我正在尝试做一个加载表单。所以我放了一个动画 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())
    

    这将返回一个boolConnectDataBase()的结果,并将 基本上与这里的另一个答案做同样的事情,只是 减少手动混乱和任务处理。

观察:通过这样的后台执行,用户可以再次单击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());
}

最新更新