ASP.NET MVC AsyncController и IO-связанные запросы - PullRequest
3 голосов
/ 28 февраля 2012

У меня есть AsyncController и домашняя страница, которая запрашивает список друзей пользователя и с ними работает некоторая база данных.Я реализовал шаблон метода асинхронного действия для любых запросов, которые вызывают внешние веб-службы.Это эффективный способ справиться с этой ситуацией?Во время большого объема запросов я иногда вижу, что IIS нуждается в потоке, и я беспокоюсь, что моя вложенная магия асинхронности может каким-то образом участвовать в этом.

Мои основные вопросы / темы для обсуждения:

  • Безопасно ли вкладывать асинхронный веб-запрос IAsyncResult в действие контроллера Async?Или это просто удваивает нагрузку где-то?
  • Эффективно ли использовать ThreadPool.RegisterWaitForSingleObject для обработки тайм-аута длительных веб-запросов или это сожжет потоки 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 секунд.

1 Ответ

1 голос
/ 28 февраля 2012

Полностью асинхронный метод, который вы вначале опишите, лучше всего подходит, так как при этом потоки TP возвращаются в пул для повторного использования. Весьма вероятно, что вы выполняете какое-то другое блокирующее действие в другом месте. Что происходит в QueryResponse? Хотя вы получаете ответ асинхронно, вы также читаете поток ответа асинхронно? Если нет, сделайте это так, тогда голодание ТП должно быть уменьшено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...