2017-04-18 59 views
5

我有一個簡單的方法:頁面裝載需要永遠

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

在我Index.cshtml:

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

這使我永遠等待!

回答

11

這是一個死鎖情況。

您使用.Result其阻塞當前線程,並等待迴應 - 而在async方法,完成後 - (由您Result),它試圖回到那個線程,但 該線程已阻塞。

你應該async/await一路(或使用ConfigureAwait(false)

+0

我明白了答案,但我怎麼能管理,以等待所有的方式?我不能等待剃刀 –

+2

我的答案是異步死鎖問題的一般形式。你不應該在View中有任何形式的線程等待邏輯。你應該在控制器*中做所有的邏輯*。 –

0

你可以試試ContinueWith的方法,但我認爲這將故障,因爲SynchronizationContext在asp.net沒那麼容易。

不壞的做法是:

控制器

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

查看:

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