Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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. 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.

like image 433
Kohins Avatar asked Aug 21 '13 22:08

Kohins


1 Answers

async doesn't magically make your UI problems disappear, but it certainly helps you manage them.

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).

So far, so good. After the delegate completes executing, BuildActual resumes execution on the UI thread and runs DoMoreStuff synchronously (on that thread).

Thus, your problems are likely due to DoMoreStuff taking up too much time. 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.

P.S. You should also avoid async void, as I explain in more detail in my MSDN article.

P.P.S. Since you're new to async, I recommend my own intro article, which has links to (IMO) the best followup resources at the end.

like image 194
Stephen Cleary Avatar answered Sep 30 '22 16:09

Stephen Cleary