简体   繁体   English

使用async / await冻结UI

[英]Freezing UI with async/await

I have some code running that will freeze up if you grab and move the window while it is loading. 我有一些代码运行,如果你在加载时抓住并移动窗口,它将冻结。 I'm not sure what the problem is but thought I would post my code since I am fairly new at working with async/await and just wondering if there is some problem with my logic. 我不确定问题是什么,但我想我会发布我的代码,因为我在处理async / await方面相当新,只是想知道我的逻辑是否存在问题。 I'm not saying this is causing the problem, I've just searched and seen other problems that with UI freezing up and async/await comes up often. 我不是说这导致了这个问题,我刚刚搜索并看到了其他问题,因为UI冻结和async / await经常出现。 Any help would be appreciated. 任何帮助,将不胜感激。

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

Thanks. 谢谢。

async doesn't magically make your UI problems disappear, but it certainly helps you manage them. async不会神奇地让你的UI问题消失,但它肯定会帮助你管理它们。

In this case, your BuildActual method (which should be named BuildActualAsync ) is first asynchronously waiting for DoStuff and MakeTimeSeries on a background thread (which should be using Task.Run instead of TaskFactory.StartNew ). 在这种情况下, BuildActual方法( 应该命名为 BuildActualAsync )首先在后台线程上异步等待DoStuffMakeTimeSeries应该使用Task.Run而不是TaskFactory.StartNew )。

So far, so good. 到现在为止还挺好。 After the delegate completes executing, BuildActual resumes execution on the UI thread and runs DoMoreStuff synchronously (on that thread). 委托完成执行后, BuildActual继续在UI线程上执行并同步运行DoMoreStuff (在该线程上)。

Thus, your problems are likely due to DoMoreStuff taking up too much time. 因此,您的问题可能是由于DoMoreStuff占用了太多时间。 If you're still not sure, application profiling (or even Debug.WriteLine combined with Stopwatch ) would give you more insight into where the UI thread is getting busy. 如果您仍然不确定,应用程序分析(甚至Debug.WriteLineStopwatch结合使用)可以让您更深入地了解UI线程忙碌的位置。

PS You should also avoid async void , as I explain in more detail in my MSDN article. PS你还应该避免async void ,我在MSDN文章中有更详细的解释。

PPS Since you're new to async , I recommend my own intro article , which has links to (IMO) the best followup resources at the end. PPS由于你是async新手,我推荐我自己的介绍文章 ,该文章链接到(IMO)最后的最佳后续资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM