我有一个 AsyncController 和一个主页,用于查询用户的 friend 列表并与他们进行一些数据库操作。我为任何调用外部 Web 服务的请求实现了异步操作方法模式。这是处理这种情况的有效方法吗?在高请求量期间,我发现 IIS 有时线程匮乏,我担心我的嵌套异步魔术可能以某种方式参与其中。
我的主要问题/谈话要点是:
- 将 IAsyncResult 异步网络请求嵌套在异步 Controller 操作中是否安全?或者这只是将某处的负载加倍?
- 使用 ThreadPool.RegisterWaitForSingleObject 处理长时间运行的 Web 请求超时是否有效,或者这会消耗 ThreadPool 线程并使应用程序的其余部分挨饿吗?
- 在 Async Controller 操作中执行同步网络请求会更高效吗?
示例代码:
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 饥饿。
关于c# - ASP.NET MVC AsyncController 和 IO 绑定(bind)请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9475060/