ASP.NET MVC AsyncController和IO绑定请求
本文关键字:IO 绑定 请求 AsyncController NET MVC ASP | 更新日期: 2023-09-27 18:26:03
我有一个AsyncController和一个主页,它可以查询用户的朋友列表并与他们一起进行一些数据库工作。我为任何调用外部web服务的请求实现了异步操作方法模式。这是处理这种情况的有效方法吗?在请求量很高的时候,我看到IIS有时线程不足,我担心我的嵌套异步魔法可能会以某种方式参与其中。
我的主要问题/谈话要点是:
- 在异步控制器操作中嵌套IAsyncResult异步web请求是否安全?或者这只是在某个地方加倍负荷
- 使用ThreadPool.RegisterWaitForSingleObject来处理长时间运行的web请求的超时是否有效,或者这会吃掉ThreadPool线程并耗尽应用程序的其余部分
- 只在异步控制器操作中执行同步web请求会更高效吗
示例代码:
public void IndexAsync()
{
AsyncManager.OutstandingOperations.Increment();
User.GetFacebookFriends(friends => {
AsyncManager.Parameters["friends"] = friends;
AsyncManager.OutstandingOperations.Decrement();
});
}
public ActionResult IndexCompleted(List<Friend> friends)
{
return Json(friends);
}
User.GetFacebookFriends(Action<List<Friend>>)
看起来像这样:
void GetFacebookFriends(Action<List<Friend>> continueWith) {
var url = new Uri(string.Format("https://graph.facebook.com/etc etc");
HttpWebRequest wc = (HttpWebRequest)HttpWebRequest.Create(url);
wc.Method = "GET";
var request = wc.BeginGetResponse(result => QueryResult(result, continueWith), wc);
// Async requests ignore the HttpWebRequest's Timeout property, so we ask the ThreadPool to register a Wait callback to time out the request if needed
ThreadPool.RegisterWaitForSingleObject(request.AsyncWaitHandle, QueryTimeout, wc, TimeSpan.FromSeconds(5), true);
}
QueryTimeout只会在超过5秒的时间内中止请求。
您首先描述的完全异步方法是最好的,因为这会将TP线程释放回池中以供重用。很有可能你正在其他地方执行一些其他的阻塞操作。QueryResponse
中发生了什么?虽然异步获取响应,但是否也异步读取响应流?如果没有,就这样做,那么TP饥饿应该减少。