0

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

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

断开连接时,列表视图项将被删除。

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

有时不显示错误,仅列出一些项目,有时显示“地址违规错误”。

正如我在使用纯 Winsock API 制作客户端/服务器应用程序之前一样,我可能使用了糟糕的 Indy 组件。

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

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

每个以某种 VCL 形式起作用的命令当然是使用 Synchronize() 进行同步的;德尔福法。

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

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

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

当我有多个连接时,这种做法非常糟糕。调试后,似乎同时执行了 Synchronize 命令,这可能导致 VCL 形式的冲突。

我不是 Indy10 的专家,任何建议都将不胜感激。

4

1 回答 1

2

通常将数据存储在 UI 中并不是一个好主意。

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

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