我需要运行与其他代码并行的繁重代码,以便用户不必等待......我正在尝试Task.Run(() =>
来完成我的任务。我的任务是使用依赖注入从服务中调用方法
我收到了以下错误:
{“依赖关系的解析失败,输入= \“Company.CacheProvider.CacheEmployeeProvider \”,name = \“(无)\”。\ r \ n发生以下情况时发生异常:解析时。\ r \ n \ nException 是:InvalidOperationException - PerRequestLifetimeManager只能 用于HTTP请求的上下文中。可能的原因 错误是在非ASP.NET应用程序上使用生命周期管理器,或 在与相关的线程无关的线程中使用它 同步 上下文。\ r \ n -------------------------------------------- --- \ r \ nAtt 异常时间,容器是:\ r \ n \ r \ n解析 Company.Provider.CacheProvider.CacheEmployeeProvider,(无)\ r \ n 解析构造函数的参数\“cache \” Company.Provider.CacheProvider.CacheEmployeeProvider(Company.Provider.Interface.IEmployeeProvider provider,Company.Provider.Interface.ICache cache)\ r \ n解析 Company.Provider.CacheProvider.RequestCache,(none)(映射自 Company.Provider.Interface.ICache,(none))\ r \ n“}
错误提供了可能的原因..但我无法找到解决方案..
整个应用程序正在使用PerRequestLifetimeManager
..如何在may任务中使用它..或者如何让我的任务在不同的上下文中运行而没有任何问题..
更新: - 注册
var container = new UnityContainer();
container.RegisterType<IEmployeeProvider>(new InjectionFactory(unity => unity.Resolve<CacheEmployeeProvider>(new DependencyOverride(typeof(IEmployeeProvider), unity.Resolve<DbEmployeeProvider>()))));
container.RegisterType<IEmployeeService, EmployeeService>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
DynamicModuleUtility.RegisterModule(typeof(Microsoft.Practices.Unity.Mvc.UnityPerRequestHttpModule));
以下是EmployeeController
依赖
[Microsoft.Practices.Unity.Dependency]
public Lazy<IEmployeeService> EmployeeService { get; set; }
发布请求
[HttpPost]
public ActionResult AddEmployee(EmployeeModel model)
{
var employee = EmployeeService.Value.Add(model);
Task.Run(() => SetupEmployeeArea(employee.Id)); //task to setup employee related data
return RedirectToAction("EmployeeList"); //redirect user to the list of employees
}
任务
async Task SetupEmployeeArea(int id)
{
EmployeeService.Value.EmployeeSetup(id); //this call firing exception
}
我也试过了,但是这段代码并没有完全执行..在调试的时候我把指针丢在了中间而没有发生任何事情。
async Task SetupEmployeeArea(int id)
{
var employeeService = DependencyResolver.Current.GetService<IEmployeeService>();
employeeService.EmployeeSetup(id); //not getting any exception and code is also not running
}
请分享建议......或者如果可能的话,请分享最好的替代品以满足我的要求(并行重载代码),除了“Hangfire”..我已经有太多的负担:)
答案 0 :(得分:2)
问题是http上下文在任务完成之前关闭。尝试使控制器的方法异步并运行如下任务:
await Task.Run(() => SetupEmployeeArea(employee.Id)); //task to setup employee related data
然后任务在http上下文关闭之前完成。
如果您想在任务完成之前返回结果,请考虑使用一些后台工作程序,如QueueBackgroundWorkItem https://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/或某些外部框架(如Hangfire),并注册您的依赖项以在http上下文之外解析。
如果在http上下文中不需要解析某些服务,则将其范围更改为另一个,例如瞬态或单身https://msdn.microsoft.com/en-us/library/ff647854.aspx。您始终可以创建自定义生命周期管理器,以便在关闭http上下文时处理案例:https://stackoverflow.com/a/4698138/9502162。
另一种方法是加载页面然后使用ajax调用来执行此任务,以便用户立即看到该页面。但是通过这种方法,您可以让客户端应用程序负责设置可能不需要的员工相关数据。