c# - 为什么在终结器中调用 Dispose() 会导致 ObjectDisposedException?

标签 c# nhibernate session transactions dispose

我有一个如下所示的 NHibernate 存储库:

public class NHibRepository : IDisposable
{
    public ISession Session { get; set; }
    public ITransaction Transaction { get; set; }

    // constructor
    public NHibRepository()
    {
        Session = Database.OpenSession();
    }

    public IQueryable<T> GetAll<T>()
    {
        Transaction = Session.BeginTransaction();
        return Session.Query<T>();
    }

    public void Dispose()
    {
        if (Transaction != null && Transaction.IsActive)
        {
            Transaction.Rollback(); // ObjectDisposedException on this line
        }

        Session.Close();
        Session.Dispose();
    }

    ~NHibRepository()
    {
        Dispose();
    }
}

当我像这样使用存储库时,它运行良好:

using (var repo = new NHibRepository())
{
    Console.WriteLine(repo.GetAll<Product>().Count());
}

但是当我这样使用它时,它会抛出一个ObjectDisposedException:

var repo = new NHibRepository();
Console.WriteLine(repo.GetAll<Product>().Count());

简单的解决方案是始终显式处理存储库,但不幸的是,我无法控制某些使用存储库的类的生命周期。

我的问题是,即使我没有显式调用 Dispose(),为什么 Transaction 已经被处理掉了?如果未明确处置,我希望存储库自动清理。

最佳答案

My question is, why is the Transaction disposed of already even though I did not explicitly call Dispose()?

也许事务的终结器首先运行。请记住,死对象的终结器可以以任何顺序在任何线程上运行,并且在终结之前不需要正确初始化。如果您不理解终结器的所有规则,那么在尝试编写更多使用终结器的代码之前,请先了解它们。这是最难做对的事情之一。

看起来您似乎错误地实现了一次性模式,这会让您感到非常悲伤。仔细阅读模式并正确执行;终结器不应该处理已经处理过的东西:

http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

关于c# - 为什么在终结器中调用 Dispose() 会导致 ObjectDisposedException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4189732/

相关文章:

c# - 构建动态表达式树以过滤集合属性

spring - 如何在 Kotlin 中使用扩展属性作为常量?

c# - session 中的数组、字典或列表?

c# - 在 C++ 中允许的函数在 C# 中不允许?

javascript - 如何将启动 Bootstrap 模板添加到 asp.net mvc web 应用程序?

performance - 在 nHibernate 关系中使用实体的 Lite 版本?

ruby - 使用 Rack::Test 使用 RSpec 测试 session 变量

python - SQLAlchemy 在多线程应用程序中正确的 session 处理

c# - Web API 2 中非常基本的不记名 token 身份验证和授权

c# - 如何在 NHibernate 中克隆对象?