使用async/await导致UI界面冻结

5

我有一些正在运行的代码,如果你在它加载时抓取并移动窗口,它就会冻结。我不确定问题出在哪里,但考虑到我在使用async/await方面还比较新手,想知道我的逻辑是否存在问题。我不是说这导致了问题,只是搜索到其他UI冻结和async/await经常出现的问题。任何帮助将不胜感激。

private async void BuildChart()
{
    DateTime date = DateTime.Today;
    using (Database db = new Database())
    {
        await BuildActual(date, db);
        await BuildActual(date.AddDays(1),db);
    }
}

private async Task BuildActual(DateTime date, Database db)
{
    List<TimeSeries> actualValues = await Task<List<TimeSeries>>.Factory.StartNew(() =>
    {
        try
        {
            var wind = DoStuff(date, db);
            if (wind == null) return null;
            if (wind.Count == 0) return null;
            return MakeTimeSeries(wind);
        }
        catch
        {
            return null;
        }
    });

    try
    {
        if (actualValues == null) return;
        DoMoreStuff(actualValues);
    }
    catch (Exception ex)
    {
        Logger.Log(ex);
    }
}

谢谢。
1个回答

18

async不会神奇地解决你的UI问题,但它确实有助于管理它们。

在这种情况下,您的BuildActual方法(应该被命名为BuildActualAsync,如所建议的)首先在后台线程上异步等待DoStuffMakeTimeSeries(应该使用Task.Run而不是TaskFactory.StartNew)。

到目前为止,一切都好。委托完成执行后,BuildActual继续在UI线程上恢复执行,并同步运行DoMoreStuff(在该线程上)。

因此,您的问题很可能是由于DoMoreStuff占用了太多时间。如果您仍然不确定,应用程序分析(甚至Debug.WriteLine结合Stopwatch)将为您提供更多关于UI线程忙碌的洞见。

P.S. 您还应该避免使用async void,如我在我的MSDN文章中所解释的那样。

P.P.S. 由于您是async的新手,我建议阅读我自己的入门文章,其中在结尾处列出了(依我个人看来)最好的后续资源链接。


感谢您提供的深入入门指南/链接。事实上,我发现问题与代码无关,但这些文章仍然对我有所帮助。 - Kohins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接