0
votes

I'm making a multi user remote administration tool, a sort of VNC but which support multi remote desktop viewer a bit like Teamviewer does.

I have a Delphi Form which only contains a TListview, this listview contains users list which are currently connected to the server.

When a connection is dropped, the listview item is deleted.

For some reason I got some random problems while deleting more than a single item, for example if I decide to flush the whole server connections, if I have more than 1 listview item, it start going crazy.

Sometimes no error show up, just some items remain listed, sometimes it shows "address violations errors".

As I was before using pure Winsock API to make Client / Server application, I maybe use badly Indy components.

A short explanation about my way of managing the Server component.

My application is Multi Server, which means user could create one or many servers at the same time. When a new Server is created by the user it run a new thread which will create a new indy Server component and setup needed events (OnConnect, OnExecute, OnDisconnect) etc...

Every commands that acts with some VCL form are of course Synchronize using the Synchronize(); delphi method.

When a new connection show up, i create from the Server Execute method a new listview item, then i set the new listview item to the AContext.data property.

When a connection is dropped on the OnDisconnect event, I delete the listview item then empty the AContext data to be sure, he wont do it again when he will be automatically destroy.

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

This way of doing works very badly when I have more than a single connection. After debugging it seems even with the Synchronize commands are executed at the same time which could result conflicts in the VCL form.

I'm not an expert in Indy10, any advice would be surely appreciate.

1
you may want to check if your .Delete call isn't executed more than once, also, you should call AContext.Data := NIL; right after .Delete, on top of that, you SHOULD check if AContext.Data <> NIL; I think your problem is that you store references to the list items badly, might wanna check out that... have fun! (:user497849

1 Answers

2
votes

Usually it is not a good idea to store your data in the UI.

Alternative answer on how might want to organize this:

  1. Store your users list in the business layer of your project.
  2. Display the users using a virtual model listview that obtains the data from the business layer. See for instance the answer at https://stackoverflow.com/a/4233875/29290
  3. Access that data in a thread safe manner (locking, etc)
  4. In the Indy 10 thread, access the data in a thread safe manner (locking, etc)
  5. Have the business layer notify the Indy and UI portions of changes in the data