【问题标题】:ObjectDisposedException - Cannot access a disposed objectObjectDisposedException - 无法访问已处置的对象
【发布时间】:2016-01-20 01:39:52
【问题描述】:

我的 WPF Windows C# 应用程序有一些问题。每当应用程序关闭时,它都会抛出一个System.ObjectDisposedException。该问题似乎仅在以 32 位编译时出现。 64 位构建运行良好,没有抛出任何异常。

从异常消息中,它说无法访问已处置的对象,但似乎无法说明是什么对象导致了问题 - 如何找出已处置的对象?

异常:抛出:“无法访问已处置的对象。” (System.ObjectDisposedException) 引发了 System.ObjectDisposedException:“无法访问已处置的对象。” 时间:1/19/2016 5:16:28 PM 主题:[1552]

异常信息:System.ObjectDisposedException 堆: 在 System.Diagnostics.EventLogInternal.OpenForWrite(System.String) 在 System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32,UInt16,System.Diagnostics.EventLogEntryType,System.String[],Byte[],System.String) 在 System.Diagnostics.EventLogInternal.WriteEntry(System.String,System.Diagnostics.EventLogEntryType,Int32,Int16,字节 []) 在 System.Diagnostics.EventLog.WriteEntry(System.String,System.Diagnostics.EventLogEntryType) 在 HP.HPTRIM.SDK.TrimApplicationBase.UnregisterStackTrace(System.Object,Int32) 在 HP.HPTRIM.SDK.Database.internal_Dispose() 在 HP.HPTRIM.SDK.Database.Finalize()

【问题讨论】:

  • HP.HPTRIM.SDK 是你的代码吗?
  • 这是我的代码正在使用的 .dll 文件
  • 要么您较早地处理了 HP 数据库,要么它是一个有缺陷的 3rd 方 SDK。堆栈跟踪还有更多内容吗?
  • 我并不特别熟悉 HP TRIM,但 Google 搜索表明有不同的 HP TRIM 库可用于针对 32 位和 64 位进行编译。在 32 位编译时,您是否切换到 32 位库?
  • @cokeman19 我会说他会是因为否则你会得到可怕的错误图像格式异常。

标签: c# wpf objectdisposedexception hp-trim


【解决方案1】:

这可能为时已晚,但我偶然发现了这一点,因为我最近在使用 HP Records Manager SDK(在我的情况下为 v8.3)时遇到了一个非常相似(相同?)的问题。我相信我已经确定了原因。

我自己的代码(一个使用 HP .Net SDK 连接到 HPRM 的可执行文件)中有一个错误,我没有在其中一个 SDK 对象上调用 Dispose())。

似乎当GC 出现在可执行文件退出时进行清理时,HP 决定要向 Windows 应用程序事件日志写入一条消息,指出开发人员忘记了该对象的 .Dispose() 正确.但是,无论出于何种原因,HP SDK 中似乎也存在一个错误,此时,它已经处理掉了用于写入事件日志的内部系统。 (有时它对我有用,有时不。可能是 SDK 中某处的竞争条件。)

结果是,在我的代码结束后,.Net 框架跳了起来,对 HP SDK 试图使用已处置的对象写入事件日志的尝试大喊大叫。

对我来说,当务之急是修复我自己的代码。一旦我处理了所有我想要的对象(特别是我创建的数据库连接),事件链并没有开始。但实际上,HP 代码似乎也有问题。

【讨论】:

  • 谢谢。这正是我为解决问题所做的。
  • 谢谢。明确的 TRIMDB.Dispose() 解决了这个问题。
【解决方案2】:

如果您查看堆栈跟踪的最后一行,您会发现问题是由 HP.HPTRIM.SDK.Database 对象的 Dispose() 引起的。

【讨论】:

    【解决方案3】:

    这不是一个答案,因为它太长而无法在评论中有用地呈现。

    我花了一些时间在ILSpy 查看EventLog 课程。异常中最里面的方法EventLogInternal.OpenForWrite 旨在在设置其内部标志之一时显式抛出ObjectDisposedException。 (尽管您收到的 ObjectDisposedException 总是可能不是专门来自这一行的,但值得注意的是。)

    private void OpenForWrite(string currentMachineName)
    {
        if (this.boolFlags[256])
            throw new ObjectDisposedException(base.GetType().Name);
        ...
    }
    

    只有在调用 EventLog 实例的 Dispose 方法时才会设置它检查的标志,这意味着 EventLog 实例正在积极处置。由于这是您无法控制的,这可能是 HP TRIM 的 HP.HPTRIM.SDK.DatabaseIDisposable 实现中的一个错误,因为异常中列出的两个 HP 方法之一将持有对 EventLog 实例的引用。

    还值得注意的是,可能会触发此异常,因为HP.HPTRIM.SDK.Database 实例在应用程序关闭期间没有被正确处理(假设它的IDisposable)并且只是被允许超出范围。作为测试,您可以尝试在应用程序关闭期间之外的某个时间处理您的 HP.HPTRIM.SDK.Database 实例,看看是否可以复制错误。

    这与比特有什么关系,我不能说。

    【讨论】:

      猜你喜欢
      • 2020-06-24
      • 2011-10-23
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多