C# MVC3 IControllerFactory Release控制器内存泄漏

C# MVC3 IControllerFactory Release控制器内存泄漏,c#,asp.net-mvc-3,design-patterns,dependency-injection,C#,Asp.net Mvc 3,Design Patterns,Dependency Injection,在我们的项目中,我们使用MefControllerFactory,这些代码是我们在global.asax中的application_start设置为ControllerBuilder.Current.SetControllerFactory(new project.Helper.MefControllerFactory(container)) 问题是,当我们最终运行.NET Profiler时,即使我们使用“ReleaseController”方法处理控制器,也会出现内存泄漏问题。原始消息是“已

在我们的项目中,我们使用MefControllerFactory,这些代码是我们在global.asax中的application_start设置为
ControllerBuilder.Current.SetControllerFactory(new project.Helper.MefControllerFactory(container))

问题是,当我们最终运行.NET Profiler时,即使我们使用“ReleaseController”方法处理控制器,也会出现内存泄漏问题。原始消息是“已释放实例,但仍可以从一个或多个根目录访问该实例。由于已释放实例通常不再使用,这可能表示内存泄漏。请调查该实例,以确定该实例是否无意中保持活动状态,或者是否可以忽略该问题。” 这个问题有什么解决办法吗

第二条消息是: “已处置具有直接EventHandler根的实例 disposed实例由EventHandler直接根目录,即该实例仅用作EventHandler的目标,不通过委托就无法从任何其他根目录访问该实例。由于不应再使用disposed实例,并且EventHandler是内存泄漏的常见原因,因此此问题强烈表明内存泄漏。”

公共类MefControllerFactory:IControllerFactory
{
私有合成容器_容器;
私有DefaultControllerFactory DefaultControllerFactory;
公共MefControllerFactory(合成容器)
{
_容器=容器;
this.defaultControllerFactory=新的defaultControllerFactory();
}
#区域IControllerFactory成员
公共IController CreateController(System.Web.Routing.RequestContext RequestContext,string controllerName)
{
i控制器控制器=空;
controller=\u container.GetExportedValueOrDefault(controllerName);
如果(控制器==null)
返回此.defaultControllerFactory.CreateController(requestContext,controllerName);
返回控制器;
}
公共无效释放控制器(IController控制器)
{
IDisposable一次性=控制器为IDisposable;
if(一次性!=null)
一次性的,一次性的;
}
#端区
public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext RequestContext,string controllerName)
{
返回System.Web.SessionState.SessionStateBehavior.Default;
}
}

谢谢…

以下是我为以下代码示例创建的基于MEF的控制器工厂:

公共类MefControllerFactory:DefaultControllerFactory
{
私有只读合成容器;
私有只读词典导出;
私有只读对象同步根;
公共MefControllerFactory(合成容器)
{
if(容器==null)
{
抛出新的ArgumentNullException(“容器”);
}
this.container=容器;
this.exports=新字典();
this.syncRoot=新对象();
}
受保护的覆盖IController GetControllerInstance(
RequestContext(请求上下文,类型控制器类型)
{
var export=this.container.GetExports(
controllerType,null,null).Single();
var controller=(IController)export.Value;
锁定(this.syncRoot)
{
this.exports.Add(控制器,导出);
}
返回控制器;
}
公共覆盖无效释放控制器(IController控制器)
{
锁定(this.syncRoot)
{
var export=this.exports[controller];
此。导出。删除(控制器);
此.container.ReleaseExport(导出);
}
基本释放控制器(控制器);
}
}
在MEF中,只能通过释放导出而不是导出值来释放对象图

public class MefControllerFactory : IControllerFactory
{
    private CompositionContainer _container;
    private DefaultControllerFactory defaultControllerFactory;

    public MefControllerFactory(CompositionContainer container)
    {
        _container = container;
        this.defaultControllerFactory = new DefaultControllerFactory();
    }

    #region IControllerFactory Members

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        IController controller = null;

        controller = _container.GetExportedValueOrDefault<IController>(controllerName);

        if (controller == null)
            return this.defaultControllerFactory.CreateController(requestContext, controllerName);

        return controller;
    }

    public void ReleaseController(IController controller)
    {
        IDisposable disposable = controller as IDisposable;
        if (disposable != null)
            disposable.Dispose();
    }

    #endregion


    public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        return System.Web.SessionState.SessionStateBehavior.Default;
    }
}
public class MefControllerFactory : DefaultControllerFactory
{
    private readonly CompositionContainer container;
    private readonly Dictionary<IController, Lazy<object, object>> exports;
    private readonly object syncRoot;

    public MefControllerFactory(CompositionContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        this.container = container;
        this.exports = new Dictionary<IController, Lazy<object, object>>();
        this.syncRoot = new object();
    }

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        var export = this.container.GetExports(
            controllerType, null, null).Single();
        var controller = (IController)export.Value;
        lock (this.syncRoot)
        {
            this.exports.Add(controller, export);
        }
        return controller;
    }

    public override void ReleaseController(IController controller)
    {
        lock (this.syncRoot)
        {
            var export = this.exports[controller];
            this.exports.Remove(controller);

            this.container.ReleaseExport(export);
        }
        base.ReleaseController(controller);
    }
}