使用async / await冻结UI

时间:2013-08-21 22:04:46

标签: c# mvvm task 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);
    }
}

感谢。

1 个答案:

答案 0 :(得分:18)

async并没有神奇地让你的UI问题消失,但它确实可以帮助你管理它们。

在这种情况下,您的BuildActual方法(should be named BuildActualAsync)首先在后台线程上异步等待DoStuffMakeTimeSeries({ {3}})。

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

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

P.S。您还应该should be using Task.Run instead of TaskFactory.StartNew,我在MSDN文章中有更详细的解释。

P.P.S。由于您是async的新用户,我建议使用avoid async void,其中包含指向(IMO​​)最佳后续资源的链接。