2017-04-18 14 views
5

Mam proste metody:Page ładowanie trwa wiecznie

public async Task<List<Steam>> Get() 
{ 
    ObjectResult result = new Models.ObjectResult(); 
    using (HttpClient client = new HttpClient()) 
    { 
     var Object = await client.GetAsync("http://api.steampowered.com/ISteamApps/GetAppList/v0001/"); 
     if (Object != null) 
     { 
      JObject steamobject = JObject.Parse(Object.ToString()); 
      var item = steamobject.SelectToken("applist").SelectToken("apps"); 
      result = JsonConvert.DeserializeObject<ObjectResult>(item.ToString()); 
     } 

    } 
    return result.MyList; 
} 

w moim Index.cshtml:

 SteamGet getter = new SteamGet(); 
     List<Steam> Games = getter.Get().Result; 
     foreach (var item in Games) 
     { 
      <li> 
       @item.Name 
      </li> 
     } 

To sprawia mi czekać na zawsze!

Odpowiedz

11

To jest sytuacja zakleszczenia.

Używasz .Result który blokuje bieżącego wątku i czeka na odpowiedź - podczas gdy w metodzie async po zakończeniu - (. Przez twoją Result) stara się wrócić do tego wątku ale że wątek jest już zablokowany .

Powinieneś async/await całą drogę (lub użyć ConfigureAwait(false))

+0

rozumiem odpowiedzi, ale w jaki sposób można zarządzać czekać całą drogę? Nie mogę się doczekać w brzytwie –

+2

Moja odpowiedź jest w ogólnej formie problemu asynchronicznego zakleszczenia. Nie powinieneś mieć żadnej logiki oczekującej wątku w jakiejkolwiek formie w widoku. Powinieneś wykonać całą logikę * w kontrolerze *. –

0

Można spróbować ContinueWith sposób, ale myślę, że będzie to wina, bo SynchronizationContext w ASP.NET nie jest tak łatwo.

Nieźle praktyka:

Controller

public async Task<List<Steam>> Get() 
{ 
    ObjectResult result = new Models.ObjectResult(); 
    using (HttpClient client = new HttpClient()) 
    { 
     var Object = await client.GetAsync("http://api.steampowered.com/ISteamApps/GetAppList/v0001/"); 
     if (Object != null) 
     { 
      JObject steamobject = JObject.Parse(Object.ToString()); 
      var item = steamobject.SelectToken("applist").SelectToken("apps"); 
      result = JsonConvert.DeserializeObject<ObjectResult>(item.ToString()); 
     } 

    } 

    SteamGet getter = new SteamGet(); 
    ViewBag.Games = await getter.Get(); 
    return result.MyList; 
    } 

Widok:

foreach (var item in (Viewag.Games as List<Steam>)) 
     { 
      <li> 
       @item.Name 
      </li> 
     }