Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当控制器的字段实现IDisposable时,如何处置控制器?_C#_Asp.net Mvc_Asp.net Mvc 3_Model View Controller_Idisposable - Fatal编程技术网

C# 当控制器的字段实现IDisposable时,如何处置控制器?

C# 当控制器的字段实现IDisposable时,如何处置控制器?,c#,asp.net-mvc,asp.net-mvc-3,model-view-controller,idisposable,C#,Asp.net Mvc,Asp.net Mvc 3,Model View Controller,Idisposable,我的控制器继承自一个类,该类包含一个实现IDisposable的字段。所以我的第一反应是写: public abstract class EventRepositoryControllerBase : Controller { protected EventRepository eventRepos { get; private set; } public EventRepositoryControllerBase(EventRepository eventRepos)

我的控制器继承自一个类,该类包含一个实现IDisposable的字段。所以我的第一反应是写:

public abstract class EventRepositoryControllerBase : Controller
{
    protected EventRepository eventRepos { get; private set; }

    public EventRepositoryControllerBase(EventRepository eventRepos)
    {
        this.eventRepos = eventRepos;
    }

    public override void Dispose()
    {
        try
        {
            base.Dispose();
        }
        finally
        {
            eventRepos.Dispose();
        }
    }
}
但这不会编译,因为控制器不会将Dispose方法标记为virtual/override。所以现在我想我被卡住了。即使我将我的方法标记为new,框架是否会保存类型为Controller的引用,因此我的方法永远不会被调用?关于如何解决这一问题的建议

更新

因此,我查看了MVC3源代码,并看到了以下内容:

 public void Dispose() {
        Dispose(true /* disposing */);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing) {
    }

所以我想我将把我的代码放在第二个方法中。但不确定此行为是否按合同指定。

ASP.NET MVC中的控制器类已正确实现IDisposable接口。如需进一步参考,请查看MSDN页面上的详细说明


要插入IDisposable接口,您需要重写已找到的受保护的dispose方法,并将用于处理“您自己的”类的逻辑放在那里。

ASP.NET MVC中的控制器类已正确实现IDisposable接口。如需进一步参考,请查看MSDN页面上的详细说明

要插入idisposable接口,您需要重写已找到的受保护的dispose方法,并将用于处理“您自己的”类的逻辑放在那里。

1)在当前类上实现接口idisposable,并执行您想要执行的操作 2) 在基类中实现该接口,然后在此类中重写它 3) 只在基类中实现该接口,不要重写 另外,您的代码看起来很奇怪,您有一个抽象类,并且您提供了实现逻辑

1)在当前类上实现接口idisposable,并执行您想要执行的操作 2) 在基类中实现该接口,然后在此类中重写它 3) 只在基类中实现该接口,不要重写
另外,你的代码看起来很奇怪,你有一个抽象类,你提供了实现逻辑,如果
IDisposable.Dispose
是用一个未密封的方法实现的,那么派生类型的代码将在基类型清理代码前后运行;由于
GC.SuppressFinalize
在派生类型完成清理(包括可能在基类型完成清理后发生的任何部分)之前不应被调用,
GC.SuppressFinalize
是在一个密封的实现中生成的,该实现反过来调用一个签名为
void Dispose(bool)
的虚拟方法

请注意,从概念上讲,在密封包装中调用虚拟方法是一个好主意,但Microsoft的实现中存在一些缺陷。最值得注意的是:

  • 由于它在基类中使用私有标志来指示对象是否已被处置,但在包装器方法中不使用该标志,因此每个希望避免重复处置的派生类也必须有自己的处置标志;
  • 派生的“Dispose”调用可以退出三种情况:
  • 它可以正常返回
  • 它可能会引发异常,但尽管如此,它已经实现了所有可以实现的功能,因此最终确定仍然应该被抑制(例如,因为“IDisposable”日志对象包装了一个文件,并且在关闭时没有成功写入文件数据)。一种丑陋的情况,但是让对象注册以进行终结并没有帮助。
  • 在对象仍有资格完成的情况下,它可能会抛出异常。 微软的“Dispose”模式无法区分后两种选择。在许多情况下,将对象注册为基于终结的清理可能是无害的,但如果使用“Finalize”方法记录调用“Dispose”的失败,则可能会导致混淆。
  • 这意味着对象通常应该包含一些通过终结来清理的资源和一些仅通过“Dispose”清理的资源,并且不通过终结来清理任何内容的未密封类型应该为可能的派生类型做出规定。实际上,带有终结器的类应该避免保存对终结不需要的任何对象的引用;需要完成的资源应该封装到它们自己的类对象中,然后由不必担心完成它们的类持有。
    早在Microsoft找到处理非托管资源的最佳方法之前,
    Dispose
    模式就是一个很好的尝试。今天,我认为最好将虚拟方法的参数视为用于更改签名的虚拟参数,而不是有意义的东西(即使在从包装器链接虚拟方法时,应该始终传递
    True

    如果
    IDisposable.Dispose
    是使用未密封的方法实现的,然后派生类型的代码将在基类型清理代码之前和之后运行;由于
    GC.SuppressFinalize
    在派生类型完成清理(包括可能在基类型完成清理后发生的任何部分)之前不应被调用,
    GC.SuppressFinalize
    是在一个密封的实现中生成的,该实现反过来调用一个签名为
    void Dispose(bool)
    的虚拟方法

    请注意,从概念上讲,在密封包装中调用虚拟方法是一个好主意,但Microsoft的实现中存在一些缺陷。最值得注意的是:

  • 由于它在基类中使用私有标志来指示对象是否已被处置,但在包装器方法中不使用该标志,因此每个希望避免重复处置的派生类也必须有自己的处置标志;
  • 派生的“Dispose”调用可以退出三种情况:
  • 它可以正常返回
  • 它可能会抛出一个EXE