Подтвердить что ты не робот

Fire and Forget с ASP.NET MVC

Я ищу информацию о лучших методах пожара и забыл действие asp.net mvc... по существу, я хочу, чтобы мобильный клиент сделал вызов; сервер запускает асинхронную задачу; а затем вернитесь к мобильному клиенту как можно быстрее.

Но я хочу убедиться, что, не допуская никаких исключений, задача async завершится успешно. Очевидно, есть несколько разных вариантов:

  • Создать новую тему
  • Очередь рабочего элемента в ThreadPool
  • Начать вызов делегата async
  • Запустить задачу

Я предполагаю, что задача будет лучшим вариантом здесь, но хотела получить мысли от SO.

Изменить: уточнить на основе нескольких ответов уже: клиенту не нужен ответ. Я хочу, чтобы HTTP-запрос был выполнен как можно быстрее, как только сервер запустил задачу async. Я знаю об асинхронных шаблонах на клиенте, однако я хочу ограничить время, необходимое мобильному устройству для поддержания открытого соединения. Кроме того, вы хотите избежать отдельного процесса, который опроса или нажал сообщение (через очередь, шину и т.д.), Потому что это перебор. Я просто хочу зарегистрировать что-то в базе данных, клиент не должен оставаться подключенным до тех пор, пока этот IO не будет завершен.

4b9b3361

Ответ 1

Я знаю, что это старый вопрос, но здесь я беру на себя такие вещи, за что это стоит, поскольку я не согласен с принятым ответом.

Вам не нужно AsyncController, потому что вам не нужно ждать завершения операций async. Поэтому ответ на ваш вопрос в отношении стороны MVC заключается в следующем: это не имеет значения. Вы можете выполнять свою работу любым способом и иметь только обычное старое действие, которое запускает процесс и возвращает любой результат, который вы хотите.

Вторая часть вашего вопроса действительно более актуальна. Вы хотите убедиться, что ничего не случится с вашими асинхронными задачами, учитывая, что вы запустили их из своего веб-процесса, считая, что сама задача не выдает исключения. Ответ на это зависит от ваших требований к надежности.

Вы упомянули, что вам не нужен отдельный процесс, и это ограничивает ваши варианты. Ваши задачи будут выполняться в одном домене приложения с вашим веб-приложением. Если что-то сбивает домен приложения или процесс, ваши задачи умрут, возможно, в странном состоянии. Это не обязательно даже из необработанных исключений. IIS может быть настроен на автоматическую переработку приложения время от времени или в определенных условиях. Или, если вы выпустите новый код или коснитесь чего-либо в каталоге bin, ваш домен приложения будет разорван после завершения всех запросов и будет запущен новый. Если эти случаи для вас - шоу-стоппер, тогда у вас нет выбора, кроме как перевести свои задачи из процесса и общаться с каким-то сообщением.

Если вы не беспокоитесь о том, что IIS убил вас, вам все равно придется беспокоиться о себе. Необработанные исключения из других фоновых задач приведут к разрушению процесса, если вы не воспользуетесь последним событием с событием AppDomain.UnhandledException. В случае использования параллельной библиотеки задач Задачи с исключениями, которые вы не наблюдаете при использовании Wait ing на них или просмотра свойств Result или Exception, приведут к разрушению процесса, если вы не используете последний шанс наблюдайте их в событии TaskScheduler.UnobservedTaskException.

Еще одно замечание: любые потоки ThreadPool, используемые для фоновых операций, не смогут выполнять запросы для вашего веб-приложения в течение этого времени. Вы можете управлять максимальными потоками в пуле или вместо этого запускать новый поток. Или, если вы используете TPL с планировщиком по умолчанию, запланируйте задачу с помощью подсказки LongRunning, чтобы эффективно получить новый поток.

Ответ 2

Очистить огонь и забыть TPL и Mvc 4

public async Task<ActionResult> Index() 
{
  // Start all operations.
  var tasks = new[]
  {
    Task.Run(() =>TestOutput.DoWork("1")), 
    Task.Run(() =>TestOutput.DoWork("2")), 
    Task.Run(() =>TestOutput.DoWork("3"))
  };

  // Asynchronously wait for them all to complete.
// Uncomment below line to not forget the results
//  var results = await Task.WhenAll(tasks);

  // Return empty string for fire and forget.
  return View(string.Empty);
} 

Ответ 3

Вы противоречивы

В заголовке вашего вопроса явно указано "Огонь и Забыть", а затем в вашем вопросе вы указываете обратное

В основном я хочу, чтобы мобильный клиент сделал вызов; сервер запускает асинхронную задачу; , а затем верните мобильному клиенту как можно быстрее.

Итак, вам нужен асинхронный вызов, который отправит результат назад или вызов Огонь и забыть?


Если обычный асинхронный вызов, просто используйте метод jQuery .ajax(), который вы одинаково используете в своей любимой библиотеке javascript, и подключите свое возвращение в функции свойств success.


Если огонь и забудьте, лучше всего попросить сервер вставить строку в таблицу TBL_JOBS в базе данных, тогда вы можете иметь повторяющийся script, который выбирает этот и обрабатывать информацию.