页面装载需要永远
问题描述:
我有一个简单的方法:页面装载需要永远
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>
}
这使我永远等待!
答
这是一个死锁情况。
您使用.Result
其阻塞当前线程,并等待回应 - 而在async
方法,完成后 - (由您Result
),它试图回到那个线程,但 该线程已阻塞。
你应该async
/await
一路(或使用ConfigureAwait(false)
)
答
你可以试试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>
}
我明白了答案,但我怎么能管理,以等待所有的方式?我不能等待剃刀 –
我的答案是异步死锁问题的一般形式。你不应该在View中有任何形式的线程等待逻辑。你应该在控制器*中做所有的逻辑*。 –