等待异步无法正常工作

时间:2018-01-12 20:00:47

标签: c# async-await

我有一个表单,我使用API​​中的数据。从服务器获取数据时,表单被阻止。我尝试使用异步等待和任务,但它没有帮助。无论如何,表格都被封锁了。你能解释一下如何在我的应用程序中应用异步等待吗?

我使用的代码:

private void navigationTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
    Task task = SwitchToProjectsPanelAsync();
    task.Wait();
}

private async Task SwitchToProjectsPanelAsync()
{
    CurrentPanel.Visible = false;

    if (MyAllProjectsFlowLayoutPanel == null)
    {
        MyAllProjectsFlowLayoutPanel = new MyAllProjectsFlowLayoutPanel(this);
        MyAllProjectsFlowLayoutPanel.SuspendLayout();
        this.Controls.Add(MyAllProjectsFlowLayoutPanel);
        MyAllProjectsFlowLayoutPanel.AllProjects = _controller.GetProjectsList();

        MyAllProjectsFlowLayoutPanel.ShowProjectsList();
        CurrentPanel = MyAllProjectsFlowLayoutPanel;
        CurrentPanel.Visible = true;
        MyAllProjectsFlowLayoutPanel.ResumeLayout(false);
        MyAllProjectsFlowLayoutPanel.PerformLayout();
    }
    else
    {
        CurrentPanel = MyAllProjectsFlowLayoutPanel;
        CurrentPanel.Visible = true;
    }
}

完整代码位于Git https://github.com/ViktorKuryshev/CRM

1 个答案:

答案 0 :(得分:1)

原因很简单:等待您创建的任务阻止了您的第一个线程:

            Task task = SwitchToProjectsPanelAsync();
            task.Wait(); // this is a blocking call

相反,您应该使用基于await的语法:

private async void navigationTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
    await SwitchToProjectsPanelAsync();
}

要注意的另一点是“等待代码中最长的部分是什么?”。我怀疑你必须将“_controller.GetProjectsList()”变成async / await,因为它也会让你陷入麻烦(经验法则:从其他线程触摸UI!你这样做了在你的SwitchToProjectsPanelAsync中。

P.S。请注意此方法签名中出现的“async void”组合。当然,您应该尽可能地避免它,并使用“异步任务”或“异步任务”。否则,异常信息无法正确传递。看到这篇不错的帖子https://haacked.com/archive/2014/11/11/async-void-methods