2013-08-24 3 views
0

Я создаю многопользовательский инструмент удаленного администрирования, своего рода VNC, но который поддерживает многопользовательский просмотрщик удаленных рабочих столов, немного похожий на Teamviewer.Лучший способ управления элементами списка из Indy 10 thread

У меня есть форма Delphi, которая содержит только TListview, этот список содержит список пользователей, которые в настоящее время подключены к серверу.

При удалении соединения элемент списка удаляется.

По какой-то причине у меня возникли некоторые случайные проблемы при удалении более одного элемента, например, если я решил сбросить все соединения с сервером, если у меня есть более одного элемента списка, он начинает сходить с ума.

Иногда не появляется ошибка, только некоторые элементы остаются в списке, иногда отображаются «ошибки нарушения адресов».

Как я и прежде, чем использовать чистый API Winsock для создания клиентского/серверного приложения, я, возможно, использую компоненты Indy плохо.

Краткое объяснение моего способа управления компонентом сервера.

Мое приложение - Multi Server, что означает, что пользователь может создать один или несколько серверов одновременно. Когда новый сервер создается пользователем, он запускает новый поток, который будет создавать новый компонентный компонент сервера и настраивать необходимые события (OnConnect, OnExecute, OnDisconnect) и т. Д.

Каждая команда, которая действует с некоторой формой VCL , конечно, синхронизируются с помощью Synchronize(); delphi.

Когда появляется новое соединение, я создаю из метода Server Execute новый элемент списка, а затем устанавливаю новый элемент listview в свойство AContext.data.

Когда соединение отключено в событии OnDisconnect, я удаляю элемент списка, а затем удаляю данные AContext, поэтому он не сделает это снова, когда он будет автоматически уничтожен.

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

Этот способ работы очень плохо, когда у меня более одного соединения. После отладки кажется, что даже с помощью команд Synchronize выполняется одновременно, что может привести к конфликтам в форме VCL.

Я не специалист в Indy10, любой совет был бы, безусловно, оценен.

+1

Вы можете проверить, не вызван ли ваш вызов .Delete более одного раза, также вы должны вызвать AContext.Data: = NIL; сразу после. Удалите, кроме того, вам ДОЛЖНО проверять, AContext.Data <> NIL; Я думаю, ваша проблема в том, что вы плохо храните ссылки на элементы списка, возможно, захотите проверить, что ... получайте удовольствие! (: – ComputerSaysNo

ответ

2

Обычно не рекомендуется хранить данные в пользовательском интерфейсе.

Альтернативный ответ о том, как могли бы организовать это:

  1. Магазин список ваших пользователей в бизнес-слой вашего проекта.
  2. Отображение пользователей с использованием списка видов виртуальной модели, которое получает данные с бизнес-уровня.Смотрите, например, ответ на https://stackoverflow.com/a/4233875/29290
  3. доступа, что данные в потокобезопасных образом (замок, и т.д.)
  4. В Indy 10 нити, доступ к данным в потокобезопасном способе (блокировки и т.д.)
  5. Имейте бизнес-уровень уведомляет Indy и пользовательский интерфейс об изменениях в данных