Это первый раз, когда я использую AsyncController (MVC3), и у меня возникли проблемы с пониманием асинхронного действия. Моя задача - импортировать умеренные объемы данных из Excel в базу данных SQL Server, используя Entity Framework. Я думал, что это будет иметь право на асинхронную операцию, и поэтому я написал контроллер для этой цели. Вот код контроллера с асинхронными действиямиАсинхронное действие AsyncController блокирует запросы вместо немедленного возврата
public class CampDonorImportController : AsyncController
{
public void CampDonorImportAsync(string fileName, int taskId) {
...
HttpContext.Application["Progress" + taskId] = 0;
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(task => {
//Code to import Excel Data
}, taskId);
}
public ActionResult CampDonorImportCompleted() {
return null;
}
public ActionResult ReportImportProgress(int taskId) {
...
return Json(new { Progress = progress, CarryOn = carryOn, Status = status }, JsonRequestBehavior.AllowGet);
}
Я называю действие Async (CampDonorImportAsync) с помощью следующей JQuery кода
$.ajax({
url: importDonorUrl,
success: function (data, textStatus, jqXHR) {
//Repeatedly call reportImportProgress
refreshTimerId = window.setInterval(reportImportProgress, reportTaskProgressTime);
},
});
reportImportProgress Javascript функции вызывает действие ReportImportProgress(), который отображает текущий прогресс асинхронное действие.
$.ajax({
url: reportTaskProgressUrl,
complete: function (jqXHR, textStatus, errorThrown) {
var json = $.parseJSON(jqXHR.responseText);
if (!json.CarryOn) {
endImportInit();
alert(json.Status);
}
},
});
Вопрос заключается в том, что вызов метода асинхронным (CampDonorImportAsync) блокирует другие запросы от одной и той же странице, например ReportImportProgress() выше. Я думал, что вызов действия Async должен немедленно вернуться, так что могут быть сделаны другие запросы, даже если задача Async все еще продолжается. Я не уверен, почему запрос Async заблокирован и ждет завершения задачи, вместо немедленного возвращения. Есть идеи ?
Да, я как бы неправильно понял все асинхронное действие. Его единственный поток IIS, который возвращается в пул, Request все еще живет. Фактически, я наткнулся на возможное решение, которое работает. Вот ссылка http://blog.janjonas.net/2012-01-02/asp_net-mvc_3-async-jquery-progress-indicator-long-running-tasks. Фактически, метод Action, который запускает новую задачу, возвращает (не дожидаясь фоновой задачи), а затем я могу вызывать действие ReprotImportProgress через регулярные промежутки времени. Он работает, но я не уверен в недостатках (если есть) – Jatin
@Nirvan: Сохранение длительных задач в памяти, таких как ссылка, которую вы опубликовали, весьма опасна. У меня есть [еще одно сообщение в блоге] (http://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html), в котором более подробно рассматривается это. –
Я реализовал решение, упомянутое в вашем сообщении в блоге. Я протестировал его, и функция Tokellation Token позволяет задачу изящно выйти. Как правило, мы будем архивировать нашу базу данных до фоновой обработки, и поэтому ваше решение подходит для моего дела. – Jatin