- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个有趣的错误需要修复。我已经准备好几个解决方案,但在我实现其中一个之前,我想问一下为什么会发生这样的错误。我问的原因是因为我无法复制这个错误所以我有点实现故障恢复解决方案。
我得到的错误是在 TList
对象上:“[EListError] 列表索引越界 (0)”。TList
包含一些 TForm
对象,我们让它们不可见,然后在该操作之后立即将它们添加到 TList
。现在我们想让它们再次可见并释放,然后将 TList
清零。当我们想让表单再次可见时会发生错误。
所以有一个循环,TList.Count
有一个值。代码进入循环并发生上述错误。以上错误不是意味着在特定索引处没有项目但列表计数大于零,这怎么可能?
这里唯一不寻常的地方可能是 for 循环倒计时,以便我们以相反的顺序显示表格。
for ii := FormListObject.Count - 1 downto 0 do begin
// Error happens here
TForm(FormListObject[ii]).Show;
end;
您认为这是一个图形用户界面线程问题、一个子项问题还是某种形式被破坏/杀死并且该列表有一个死引用?我仍然认为这个错误意味着索引 0 处没有 TList 项,死引用应该触发访问冲突错误,不是吗?
最佳答案
三种可能的原因:
内存覆盖恰好覆盖了“可访问”内存中的内容(因此没有 AV)。但是会触发对 FormListObject
的无效更改。
其他东西(比如 OnShow 事件)实际上是从 FormListObject
中删除项目。它不必是不同的线程;但当然这也是可能的。 注意:虽然您询问这是否是 GUI 线程问题,但我真的怀疑是不是这种情况,因为您必须专门从不同的线程调用 GUI 代码以应对这种可能性。
可重入代码导致 FormListObject
在循环中间被更改。当您在处理另一条消息的过程中调用 Application.ProcessMessages
时,就会发生这种情况。 我的调试意识在这个上抽搐。即使您没有犯下 Application.ProcessMessages
罪,您所显示的表单上的某些组件也可能是。
PS: I notice in a comment you say you already have a stack-trace. Check further down the stack-trace, and see if your code is re-entrant.
由于您无法重现该问题,您需要额外的调试日志记录以获取更多信息。假设您有简单地附加到调试文件的 Log 方法。 (日志方法应输出当前线程 ID 以确认线程问题。)添加调试日志记录如下:
Log('Start loop');
for ii := FormListObject.Count - 1 downto 0 do begin
// Error happens here
TForm(FormListObject[ii]).Show;
end;
Log('End loop');
封装您的 FormListObject
以便任何用于移除/删除/清除项目的代码都在您的控制下通过代码。 IE。不要暴露对底层列表的直接访问,这将允许流氓代码在没有您的知识的情况下更改列表。然后在任何可以删除项目的方法上添加日志记录:
Log(Format('(%p)FormListObject.Clear', [Pointer(Self)]));
记录 FormListObject
实例的创建/销毁也可能有用。
当问题发生时,您必须分析日志文件以确定出了什么问题。例如,如果我对问题最可能原因的预感是正确的,您可能会发现以下模式(注意每个条目都在同一个线程上):
(Thread X) Start Loop
(Thread X) Start Loop
(Thread X) End Loop
(Thread X) ($........) Clear
我添加了第三种可能性;我实际上有一种预感是最有可能的原因。
还添加了一些具体的调试建议以缩小范围。
关于delphi - EListError 列表索引越界 (0) - TForm 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23410796/
我有一个有趣的错误需要修复。我已经准备好几个解决方案,但在我实现其中一个之前,我想问一下为什么会发生这样的错误。我问的原因是因为我无法复制这个错误所以我有点实现故障恢复解决方案。 我得到的错误是在 T
我正在将旧的 Delphi 7 代码迁移到 Delphi XE4。我在 Delphi XE4 应用程序中使用 DevExpress 13.1 并使用 DevExpress ExpressBars 功能
我是一名优秀的程序员,十分优秀!