【问题标题】:Autofac and HostingEnvironment.QueueBackgroundWorkItemAutofac 和 HostingEnvironment.QueueBackgroundWorkItem
【发布时间】:2014-06-29 06:39:29
【问题描述】:

我希望为我的 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 的执行方法内部(它位于与 ASP.NET MVC 项目不同的程序集中:

        public bool Execute()
    {


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

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

        ...

    }

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

现在,我对 Autofac 的了解还不够,无法找出解决此问题的最佳方法。是否有可能直接在 ExecuteTask 方法中重新注入引用?如果是这样 - 如何?

我将非常感谢任何帮助。这几天一直让我发疯......

谢谢, 尼克·戈洛博罗德科

【问题讨论】:

    标签: asp.net-mvc autofac


    【解决方案1】:

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

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

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

     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

    希望这可以为将来的其他人节省一点时间!

    【讨论】:

      猜你喜欢
      • 2019-11-15
      • 2016-09-10
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多