使用async/await冻结UI

本文关键字:冻结 UI await async 使用 | 更新日期: 2023-09-27 18:28:37

我运行了一些代码,如果在加载窗口时抓取并移动窗口,这些代码就会冻结。我不确定问题出在哪里,但我想我会发布我的代码,因为我对async/await还很陌生,只是想知道我的逻辑是否有问题。我并不是说这会导致问题,我只是搜索并看到了UI冻结和异步/等待经常出现的其他问题。如有任何帮助,我们将不胜感激。

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);
    }
}

谢谢。

使用async/await冻结UI

async不会神奇地让UI问题消失,但它确实有助于您管理这些问题。

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

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

因此,您的问题可能是由于DoMoreStuff占用了太多时间。如果您仍然不确定,应用程序评测(甚至Debug.WriteLineStopwatch相结合)会让您更深入地了解UI线程的繁忙情况。

附言:您还应该避免async void,正如我在MSDN文章中更详细地解释的那样。

附言:由于你是async的新手,我推荐我自己的介绍文章,文章末尾有(IMO)最佳后续资源的链接。