【问题标题】:ASP.NET MVC AsyncController and IO-bound requestsASP.NET MVC AsyncController 和 IO 绑定请求
【发布时间】:2012-02-28 09:45:50
【问题描述】:

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

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

  • 在 Async 控制器操作中嵌套 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&lt;List&lt;Friend&gt;&gt;) 看起来像这样:

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 秒时中止请求。

【问题讨论】:

    标签: c# asp.net-mvc asynchronous


    【解决方案1】:

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

    【讨论】:

    • 天哪,我只是使用 StreamReader 的 ReadToEnd() 来读取 Stream,那就这样吧。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2013-12-08
    • 1970-01-01
    • 2011-01-20
    相关资源
    最近更新 更多