2013-08-21 18 views
5

Ich habe einige Code ausgeführt, die einfrieren, wenn Sie greifen und das Fenster verschieben, während es geladen wird. Ich bin nicht sicher, was das Problem ist, aber dachte, dass ich meinen Code posten würde, da ich ziemlich neu in der Arbeit mit async bin/warte und nur frage mich, ob es ein Problem mit meiner Logik gibt. Ich sage nicht, dass das das Problem verursacht, ich habe gerade andere Probleme gesucht und gesehen, dass mit der Einfrieren der Benutzeroberfläche und async/warten oft aufkommt. Jede Hilfe wäre willkommen.Freezing UI mit async/erwarten

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

Danke.

Antwort

18

async macht Ihre UI-Probleme nicht magisch verschwinden, aber es hilft Ihnen sicher, sie zu verwalten. erste asynchron wartet auf DoStuff und MakeTimeSeries auf einem Hintergrund-Thread

In diesem Fall Ihre BuildActual Methode (die should be namedBuildActualAsync) (die should be using Task.Run instead of TaskFactory.StartNew).

So weit, so gut. Nachdem der Delegat seine Ausführung abgeschlossen hat, setzt die Ausführung auf dem UI-Thread fort und führt DoMoreStuff synchron (auf diesem Thread) aus.

Daher sind Ihre Probleme wahrscheinlich aufgrund DoMoreStuff zu viel Zeit in Anspruch nehmen. Wenn Sie sich immer noch nicht sicher sind, gibt Ihnen die Anwendungsprofilerstellung (oder sogar Debug.WriteLine in Kombination mit Stopwatch) einen besseren Einblick darüber, wo der UI-Thread gerade beschäftigt ist.

P.S. Du solltest auch avoid async void, wie ich in meinem MSDN-Artikel ausführlicher erläutere.

P.P.S. Da Sie neu bei async sind, empfehle ich my own intro article, die Links zu (IMO) die besten Follow-up-Ressourcen am Ende hat.

+0

Danke für die eingehende Anleitung/Links. Ich fand heraus, dass das Problem nichts mit dem Code zu tun hat, aber die Artikel haben trotzdem geholfen. – Kohins