从Indy 10线程管理Listview项目的最佳方法

时间:2013-08-24 11:33:36

标签: delphi object indy

我正在制作一个多用户远程管理工具,一种VNC但支持多远程桌面查看器,有点像Teamviewer。

我有一个只包含TListview的Delphi表单,这个listview包含当前连接到服务器的用户列表。

删除连接后,列表视图项将被删除。

出于某种原因,我在删除多个项目时遇到了一些随机问题,例如,如果我决定刷新整个服务器连接,如果我有超过1个listview项目,它就会开始变得疯狂。

有时候没有错误显示,只有一些项目仍然列出,有时它会显示"地址违规错误"。

就像我之前使用纯Winsock API来制作客户端/服务器应用程序一样,我可能会使用非常糟糕的Indy组件。

关于我管理服务器组件的方式的简短说明。

我的应用程序是多服务器,这意味着用户可以同时创建一个或多个服务器。 当用户创建新服务器时,它会运行一个新线程,该线程将创建一个新的indy Server组件并设置所需的事件(OnConnect,OnExecute,OnDisconnect)等......

每个使用某种VCL格式的命令当然都是使用Synchronize()进行同步;德尔菲法。

当出现新连接时,我从Server Execute方法创建一个新的listview项,然后我将新的listview项设置为AContext.data属性。

当在OnDisconnect事件上删除连接时,我删除了listview项,然后清空AContext数据以确保,当他将自动销毁时,他不会再这样做。

Synchronize(procedure begin
TListItem(AContext.data).Delete;
end);
AContext.data := nil;

当我有多个连接时,这种做法非常糟糕。调试之后,即使同时执行Synchronize命令也可能导致VCL格式发生冲突。

我不是Indy10的专家,任何建议都一定会受到赞赏。

1 个答案:

答案 0 :(得分:2)

通常,将数据存储在用户界面中并不是一个好主意。

关于如何组织这个的替代答案:

  1. 将您的用户列表存储在项目的业务层中。
  2. 使用从业务层获取数据的虚拟模型列表视图显示用户。例如,请参阅https://stackoverflow.com/a/4233875/29290
  3. 上的答案
  4. 以线程安全的方式访问该数据(锁定等)
  5. 在Indy 10线程中,以线程安全的方式访问数据(锁定等)
  6. 让业务层通知Indy和UI部分数据中的更改