将温莎城堡注入的依赖项传递给并行线程 - Dispose() 问题
我使用 ASP.NET MVC 和 Castle Windsor 作为我的 IoC 容器,并将组件生活方式设置为 PerWebRequest。我的存储库(即注入的依赖项)在构造函数中创建实体框架的 ObjectContext 实例,并将其存储在私有实例变量中。我的存储库实现了 IDisposable,并在 Dispose 方法中处理了 ObjectContext。我认为所有这些都是非常标准的,这里有一个简化的说明:
存储库:
public class Repository : IRepository {
private MyContext _dc; // MyContext inherits from ObjectContext
public Repository() {
_dc = new MyContext();
}
public void Dispose() {;
_dc.Dispose();
}
}
为了确保没有内存泄漏并且调用我的存储库的 Dispose(),我重写 DefaultControllerFactory 的 ReleaseController 方法来释放 Windsor 的容器:
public class WindsorControllerFactory : DefaultControllerFactory {
IWindsorContainer _container;
public WindsorControllerFactory(IWindsorContainer container) {
_container = container;
// Do stuff to register all controller types
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
// Do stuff to resolve dependency
}
public override void ReleaseController(IController controller) {
// by releasing the container, Windsor will call my Dispose() method on my repository
_container.Release(controller);
base.ReleaseController(controller);
}
}
我认为所有这一切都很漂亮标准。但是,我想分离一个并行线程,并在该并行线程内利用 IRepository 依赖项。我的问题是,我的存储库在我使用它时已经被处置了:
public class HomeController : Controller {
IRepository _repository;
public HomeController(IRepository repository) {
_repository = repository;
}
public ActionResult Index() {
var c = _repository.GetCompany(34);
new Task(() => {
System.Threading.Thread.Sleep(2000); // simulate long running task
// will throw an error because my repository (and therefore, ObjectContext) will have been disposed.
var c2 = _repository.GetCompany(35);
}).Start();
return Content(c.Name, "text/plain");
}
}
其他人如何解决这个问题?如何将依赖项传递给并行线程?
提前致谢。
I'm using ASP.NET MVC with Castle Windsor as my IoC container with the component lifestyle set to PerWebRequest. My repository (which is the dependency that's injected) creates an instance of Entity Framework's ObjectContext in the constructor and I store that in a private instance variable. My repository implements IDisposable and inside my Dispose method, I dispose the ObjectContext. I think all of this is pretty standard and here's a simplified illustration:
Repository:
public class Repository : IRepository {
private MyContext _dc; // MyContext inherits from ObjectContext
public Repository() {
_dc = new MyContext();
}
public void Dispose() {;
_dc.Dispose();
}
}
To ensure that there's no memory leak and that my Repository's Dispose() is called, I override DefaultControllerFactory's ReleaseController method to release Windsor's container:
public class WindsorControllerFactory : DefaultControllerFactory {
IWindsorContainer _container;
public WindsorControllerFactory(IWindsorContainer container) {
_container = container;
// Do stuff to register all controller types
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
// Do stuff to resolve dependency
}
public override void ReleaseController(IController controller) {
// by releasing the container, Windsor will call my Dispose() method on my repository
_container.Release(controller);
base.ReleaseController(controller);
}
}
I think all of this is pretty standard. However, I'd like to spin off a parallel thread, and inside that parallel thread utilize the IRepository dependency. My problem is that my repository will have already been disposed by the time I use it:
public class HomeController : Controller {
IRepository _repository;
public HomeController(IRepository repository) {
_repository = repository;
}
public ActionResult Index() {
var c = _repository.GetCompany(34);
new Task(() => {
System.Threading.Thread.Sleep(2000); // simulate long running task
// will throw an error because my repository (and therefore, ObjectContext) will have been disposed.
var c2 = _repository.GetCompany(35);
}).Start();
return Content(c.Name, "text/plain");
}
}
How do other people solve this problem? How do you pass your dependencies to a parallel thread?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
创建一个新的存储库实例。 ObjectContext 的构建成本低廉。
或者,您可以将处理存储库的责任附加到长时间运行的线程。我搞乱了它,我认为对代码的这些更改将解决您的问题:
在您的 WindsorControllerFactory 中
、在 HomeController 中
以及新的基本控制器中
Create a new Repository instance. ObjectContexts are inexpensive to construct.
OR, you could attach the responsibility of disposing the Repository to the long running thread. I messed around with it, I think these alterations to your code will solve your problem:
In your WindsorControllerFactory
In HomeController
And the new base controller