ASP.NET MVC AsyncController和IO绑定请求

时间:2012-02-28 01:24:15

标签: c# asp.net-mvc asynchronous

我有一个AsyncController和一个主页,用于查询用户的好友列表并使用它们进行数据库处理。我为任何调用外部Web服务的请求实现了异步操作方法模式。这是处理这种情况的有效方法吗?在高请求量的时候,我看到IIS有时会被线程匮乏,我担心我的嵌套异步魔法可能会以某种方式参与其中。

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

  • 在Async控制器操作中嵌套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);
}

如果请求超过5秒,则QueryTimeout只会中止请求。

1 个答案:

答案 0 :(得分:1)

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