使用async/await冻结UI

Koh*_*ins 5 c# task mvvm async-await

我有一些代码运行,如果你在加载时抓住并移动窗口,它将冻结.我不确定问题是什么,但我想我会发布我的代码,因为我在使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Ste*_*ary 18

async 不会神奇地让你的UI问题消失,但它肯定会帮助你管理它们.

在这种情况下,你的BuildActual方法(这应该被命名 BuildActualAsync)是第一异步地等待DoStuff,并MakeTimeSeries在后台线程(这应该使用Task.Run代替TaskFactory.StartNew).

到现在为止还挺好.委托完成执行后,BuildActual继续在UI线程上执行并DoMoreStuff同步运行(在该线程上).

因此,您的问题可能是由于DoMoreStuff占用了太多时间.如果您仍然不确定,应用程序分析(甚至Debug.WriteLine与之结合使用Stopwatch)可以让您更深入地了解UI线程忙碌的位置.

PS你也应该避免async void,正如我在MSDN文章中详细解释的那样.

PPS由于您是新手async,我推荐自己的介绍文章,该文章最后链接到(IMO)最佳后续资源.