2012-02-28 79 views
4

我有一个AsyncController和一个主页,查询用户的朋友列表,并做一些数据库工作。我为调用外部Web服务的任何请求实现了异步操作方法模式。这是处理这种情况的有效方式吗?在高请求量的时代,我看到IIS有时会陷入线程匮乏的状态,我担心我的嵌套异步魔法可能会以某种方式参与其中。ASP.NET MVC的AsyncController和IO绑定请求

我的主要问题/谈话要点是:

  • 它是安全的窝一个异步控制器动作里面一个IAsyncResult异步Web请求?或者这只是加倍负载的地方?
  • 使用ThreadPool.RegisterWaitForSingleObject处理长时间运行的Web请求的超时效率,还是会消耗ThreadPool线程并使应用程序的其余部分无效?
  • 在Async Controller操作中执行同步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秒。

回答

1

您首先描述的完全异步方法是最好的,因为这会将TP线程释放回池以供重用。您在其他地方执行其他阻止操作的可能性很大。 QueryResponse会发生什么?尽管您异步获取响应,您是否也异步读取响应流?如果不是这样,那么应该减少TP饥饿。

+0

呵呵drat我正在使用StreamReader的ReadToEnd()读取Stream,那就是它了。谢谢 :) – Foritus 2012-02-28 02:06:41