Autofac и среда размещения.Элемент QueueBackgroundWorkItem

#asp.net-mvc #autofac

#asp.net-mvc #автофас

Вопрос:

Я хочу добавить некоторую фоновую обработку в свой ASP.NET Приложение MVC 5, более конкретно выполняющее некоторые длительные (5-10 секунд) запущенные задачи с HostingEnvironment.Элемент QueueBackgroundWorkItem. Теперь проблема, с которой я сталкиваюсь, заключается в том, что код выполняется «вне диапазона» и больше не привязан к запросу — Autofac избавляется от некоторых введенных зависимостей.

Вот часть кода:

         [HttpPost, ActionName("Execute")]
    public ActionResult ExecutePost(Guid taskguid, FormCollection values)
    {
        if (taskguid == default(Guid))
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        var model = _taskListService.GetTaskByGuid(taskguid);

        if (TryUpdateModel(model.TaskObject as MissingCrossReferenceTask))
        {
            model.TaskObject.DependencyContainer = _dependencyContainer;
            model.TaskObject.TaskListId = model.Id;

            HostingEnvironment.QueueBackgroundWorkItem(ct => ExecuteTask(ct, model));

            return RedirectToAction("Index", "Dashboard");
        }


        return View(model);

    }
 

В приведенном выше коде DependencyContainer — это объект, содержащий ряд зависимостей, которые вводятся Autofac (репозитории и службы EF)

 private void ExecuteTask(CancellationToken ct, TaskList model)
    {
        model.TaskObject.Execute();
    }
 

Внутри этого метода выполнения MissingCrossReferenceTask (который находится в отдельной сборке от ASP.NET Проект MVC:

         public bool Execute()
    {


        long tableId = DependencyContainer.CrossReferenceService.GetCrossReferenceTable(TableName).Id;

        string currentValue = DependencyContainer.CrossReferenceService.GetValue(FromValue, tableId);

        ...

    }
 

Первая строка выдает исключение: ObjectDisposedExcetion {«Экземпляр ObjectContext удален и больше не может использоваться для операций, требующих подключения».}

Так вот, я недостаточно хорошо знаю Autofac, чтобы найти наилучший способ обойти эту проблему. Можно ли каким-то образом повторно ввести ссылку непосредственно в метод executeTask? Если да, то каким образом?

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

Спасибо, Ник Голобородько

Ответ №1:

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

Я думаю, что нашел способ обойти это (другими словами — теперь все работает так, как мне бы хотелось). Я все еще не уверен, является ли этот подход лучшим в моей ситуации или есть какие-то невидимые проблемы с ним — я был бы очень признателен за любые комментарии по этой теме!

Я решил эту проблему следующим образом:

  private void ExecuteTask(CancellationToken ct, TaskList model)
    {
        MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;

        using (var container = app.ContainerProvider.ApplicationContainer.BeginLifetimeScope(WebLifetime.Application))
        {
            model.TaskObject.DependencyContainer = container.Resolve<DependencyContainer>();
            model.TaskObject.Execute();
        }
    }
 

(принято из решения, размещенного на этой странице: http://aboutcode.net/2010/11/01/start-background-tasks-from-mvc-actions-using-autofac.html )

Надеюсь, это сэкономит немного времени кому-то еще в будущем!