Методы броска в задачу, чтобы избежать блокировки потока asp.net

Мне интересно, имеет ли следующий код какой-либо доступ, который мне неизвестен при работе на веб-сервере. Чтение отличной серии http://reedcopsey.com/series/parallelism-in-net4/ Я не могу найти что-либо, что конкретно связано с моим вопросом, то же самое с msdn, поэтому я подумал, d принесите его сюда.

Пример вызова:

public ActionResult Index() {
    ViewBag.Message = "Welcome to ASP.NET MVC!";

    Task.Factory.StartNew(() => {
        //This is some long completing task that I don't care about
        //Say logging to the database or updating certain information
        System.Threading.Thread.Sleep(10000);
    });

    return View();
}

Ответ 1

ASP.Net поддерживает асинхронные страницы, см. Асинхронные страницы в ASP.NET, но является сложной моделью программирования и вообще не связывается с MVC. При этом запуск асинхронных задач из обработчика синхронных запросов выполняется до некоторой точки:

  • если скорость, с которой запросы добавляют новые задачи, превышает среднюю скорость обработки, ваш процесс в конечном итоге потерпит крах. Задачи занимают живую память, и в конечном итоге они заполнят очереди в памяти, где они хранятся, и вы начнете получать сбои.
  • .NET Taks по своей сути ненадежны, поскольку им не хватает постоянного хранилища, поэтому все задачи, которые передаются async, должны быть потоковыми как "откатные", т.е. если они никогда не завершатся, нет никакой потери для приложения или для пользователя, делающего запрос. Если задача важна, она должна быть отправлена ​​через надежный механизм, гарантирующий выполнение при наличии сбоев, как показано в Выполнение асинхронной процедуры.

Ответ 2

В этом случае важно убедиться, что код, содержащийся внутри задачи, обернут в блок try/catch или все возможные исключения, возникающие в этом потоке, будут распространяться. Вы также должны убедиться, что в этой долговременной задаче вы не получаете доступа к каким-либо из элементов контекста Http, таких как Request, Response, Session,... поскольку они могут быть недоступны к моменту доступа к ним.

Ответ 3

Используйте new Thread вместо Task.Factory.StartNew. Task.Factory.StartNew используйте поток из пула потоков, и если у вас будет много фоновых задач, у пула потоков будет закончиться поток и ухудшит ваше веб-приложение. Запросы будут поставлены в очередь, и ваше веб-приложение в конечном итоге умрет.

Вы можете проверить, работает ли ваша фоновая работа в пуле потоков с помощью Thread.CurrentThread.IsThreadPoolThread. Если вы вернетесь, используется пул потоков.