c#winforms我的用户界面在事件加载中仍然冻结

时间:2018-11-15 15:21:26

标签: c# .net winforms asynchronous async-await

在加载表单的事件时,我调用方法loadDg

private void form_Load(object sender, EventArgs e)
{
  loadDg();
}

private async Task loadDg()
        {
            pictureLoading.Visible = true;
            await Task.Run(() => { string[] datas = db.row("select * from products");
string[] datas2 = db.row("select * from users");
double one = Convert.ToInt32(datas[0]);
label1.Text = one.toString();
//....
});
pictureLoading.Visible = false; //hide gif animation 
}

在我的代码db.row中,此方法始终仅返回1行(字符串数组),但是我的ui仍然冻结,我尝试使用异步方式连续更新UI,而在启动时不冻结

3 个答案:

答案 0 :(得分:0)

没有什么可以阻止您的代码异步运行。 pictureLoading即使在任务完成之前也将不可见。您应按以下方式解决界面的跨线程问题和逻辑:

private void form_Load(object sender, EventArgs e)
{
  pictureLoading.Visible = true;
  loadDg();
}


private async Task loadDg()
{

    await Task.Run(() =>
    {
        string[] datas = db.row("select * from products");
        string[] datas2 = db.row("select * from users");
        double one = Convert.ToInt32(datas[0]);

        label1.BeginInvoke((Action)delegate ()
        {
            label1.Text = one.toString();
            //hide gif animation 
            pictureLoading.Visible = false;
        });
        //....
    });

}

答案 1 :(得分:0)

应避免不必要地在线程/上下文之间跳转。

这具有更好的资源使用率:

private async void form_Load(object sender, EventArgs e)
{
    pictureLoading.Visible = true;

    try
    {
        label1.Text = await LoadDgAsync();
    }
    catch
    {
        // error handling
    }
    finally
    {
        pictureLoading.Visible = false;
    }
}


private Task<string> LoadDgAsync()
{
    return Task.Run(() =>
    {
        string[] datas = db.row("select * from products");
        string[] datas2 = db.row("select * from users");
        double one = Convert.ToInt32(datas[0]);

        //....

        return one.toString();
    });
}

答案 2 :(得分:-2)

您正在同步调用loadDg()函数。

除非您等待loadDg()函数调用(因为它的返回类型是Task)并且使form_Load函数异步,否则函数调用将是同步的。

正确的解决方法是...

private async void form_Load(object sender, EventArgs e)
{
  await loadDg();
}