释放包含TJvAppDBStorage的数据模块会在TComponent.RemoveNotification()中引发访问冲突

时间:2013-03-18 12:17:33

标签: delphi delphi-xe2 jvcl

我有一个我无法释放的数据模块(听起来很有趣)。无论我是尝试手动销毁它,还是让其他组件(甚至是Application)为我做这件事,我都会得到一个带有此堆栈跟踪的AV:

exception class   : EAccessViolation
exception message : Access violation at address 0048FC2B in module 'Instruments.exe'. Read of address 80808088.

main thread ($1e28):
0048fc2b Instruments.exe System.Classes    TComponent.RemoveNotification
00408a01 Instruments.exe System         57 @Halt0
00ac86f0 Instruments.exe Instruments    82 initialization

此数据模块包含一堆TADOxxx个组件,另外两个TJvDataSource,一个TApplicationEvents,一个TClientDataSet和一个TJvAppDBStorage。它的代码只包含打开ADO连接,将一些记录写入表,运行一些查询等等(没什么不寻常的)。除了我上面提到的内容之外,它不会拥有任何其他组件。我很困惑这个虚假的RemoveNotificaion()来自哪里。有什么想法吗?

更新

删除TJvAppDBStorage后,我可以销毁数据模块。这是组件的属性:

object AppStorage: TJvAppDBStorage
  StorageOptions.BooleanStringTrueValues = 'TRUE, YES, Y'
  StorageOptions.BooleanStringFalseValues = 'FALSE, NO, N'
  DataSource = dsConfiguration
  KeyField = 'Key'
  SectionField = 'Section'
  SubStorages = <>
  ValueField = 'Value'
  Left = 272
  Top = 304
end

有没有人用过JvAppDBStorage?这是正常预期的行为吗?

1 个答案:

答案 0 :(得分:2)

我没有JvAppDBStorage的经验,但我可以猜测发生了什么。

此组件将设置存储到数据库,由DataSource实例的JvAppDBStorage属性指定。在你的情况下是dsConfiguration。因此,为了实现这一切,只要dsConfiguration读取和写入设置,您就需要AppStorage可用。我敢打赌,当dsConfiguration试图存储AppStorage时,AppStorage已被销毁。我希望在dsConfiguration被释放时会发生这种情况。因此,问题的解释是在AppStorage之前释放dsConfiguration

解决方案是确保在释放AppStorage时{{1}}仍然有效。