2017-04-18 56 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> 
     }