Autofac和HostingEnvironment.QueueBackgroundWorkItem

时间:2014-06-29 06:39:30

标签: asp.net-mvc autofac

我希望在我的ASP.NET MVC 5应用程序中添加一些后台处理,更具体地说,使用HostingEnvironment.QueueBackgroundWorkItem执行一些长时间(5-10秒)的运行任务。现在,我遇到的问题是代码运行“带外”并且不再依赖于请求 - 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的execute方法内部(与ASP.NET MVC项目分开的程序集中:

        public bool Execute()
    {


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

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

        ...

    }

第一行引发异常:ObjectDisposedExcetion {“ObjectContext实例已被释放,不能再用于需要连接的操作。”}

现在,我不知道Autofac是否能够找到解决此问题的最佳方法。是否有可能在ExecuteTask方法中直接重新引入引用?如果是这样 - 怎么样?

我非常感谢任何帮助。它已经让我疯了几天了......

谢谢, 尼克Goloborodko

1 个答案:

答案 0 :(得分:0)

我想提交问题迫使我从一个稍微不同的角度来看问题。

我想我已经找到了解决这个问题的方法(换句话说 - 它现在可以按照我的意愿运行)。我仍然不确定这种方法在我的情况下是否是最好的,或者是否有任何看不见的问题 - 我非常感谢有关这个主题的任何评论!

我已通过以下方式解决了这个问题:

 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

希望将来可能会为其他人节省一些时间!