显然HttpClient只允许Asnyc调用?
当然,您可以将“.Result”称为 so:
public ActionResult Index()
{
var someImportantData = httpClient.ReadAsStringAsync().Result; // Aparently I shouldn't do this according to the article.
// or
var someImportantData = Task.Run(() => Client.PostAsync()).Result;
Return View( new MyViewModel(someImportantData));
}
使其同步,但这显然非常危险,应该避免,因为它会导致死锁,如here.所述
那么我对同步请求的选择是什么?我是否会强迫使用较旧的HttpWebRequest?在我特定的MVC操作中,我希望调用是同步的,因为我不想返回页面,直到我从一个宁静的api调用中收集数据。
答案 0 :(得分:3)
如果使用异步API,则应始终使代码异步。您可以轻松地await
异步成员。
public async Task<ActionResult> Index() {
var someImportantData = await httpClient.ReadAsStringAsync(...);
return View(new MyViewModel(someImportantData));
}
我希望我的当前线程不继续(即:同步)并等待API调用返回,然后我可以重定向到新页面。
在您从restful API调用中收集数据之前,上述调用不会返回该页面。等待之后的所有内容都将返回原始主题。
.Result
会导致死锁,如文章中所述。
是。你应该避免混合异步和阻塞呼叫。
答案 1 :(得分:0)
你真的不需要在这里使用.Result
。您只需await
即可获得结果:
例如:
public async Task<ActionResult> Index()
{
var someImportantData = await httpClient.ReadAsStringAsync().ConfigureAwait(false);
return View( new MyViewModel(someImportantData)); // This line will not be called until previous line is completed.
}
使用ConfigureAwait(false)
可选。如果您没有使用ASP.NET Core,那么它可以帮助您,因为您不需要捕获服务器端代码的上下文。请参阅this link。