Най-добрият начин за управление на елементите на Listview от нишката на Indy 10

Създавам многопотребителски инструмент за отдалечено администриране, нещо като VNC, но който поддържа многофункционален преглед на отдалечен работен плот, малко като Teamviewer.

Имам формуляр на Delphi, който съдържа само TListview, този списък съдържа списък с потребители, които в момента са свързани към сървъра.

Когато връзката бъде прекъсната, елементът на списъка се изтрива.

По някаква причина имам някои произволни проблеми, докато изтривам повече от един елемент, например ако реша да изтрия целите сървърни връзки, ако имам повече от 1 елемент за изглед на списък, започва да полудява.

Понякога не се показва грешка, само някои елементи остават в списъка, понякога показва „грешки при нарушения на адреси“.

Както използвах преди да използвам чист Winsock API, за да направя приложение за клиент/сървър, може би използвам зле компоненти на Indy.

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

Моето приложение е Multi Server, което означава, че потребителят може да създаде един или много сървъри едновременно. Когато нов сървър е създаден от потребителя, той стартира нова нишка, която ще създаде нов indy сървърен компонент и ще настрои необходимите събития (OnConnect, OnExecute, OnDisconnect) и т.н...

Всички команди, които действат с някаква VCL форма, разбира се, се синхронизират с помощта на Synchronize(); делфи метод.

Когато се появи нова връзка, аз създавам от метода Server Execute нов елемент на списък, след което задавам новия елемент на списък на свойството AContext.data.

Когато връзката се прекъсне при събитието OnDisconnect, изтривам елемента за изглед на списък, след което изпразвам данните на AContext, за да съм сигурен, че той няма да го направи отново, когато бъде автоматично унищожен.

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

Този начин на работа работи много зле, когато имам повече от една връзка. След отстраняване на грешки изглежда, че дори когато командите за синхронизиране се изпълняват едновременно, което може да доведе до конфликти във формата VCL.

Не съм експерт по Indy10, всеки съвет със сигурност ще съм благодарен.


person Ricky16    schedule 24.08.2013    source източник
comment
може да искате да проверите дали вашето извикване .Delete не се изпълнява повече от веднъж, също така трябва да извикате AContext.Data := NIL; веднага след .Delete, освен това ТРЯБВА да проверите дали AContext.Data ‹› NIL; Мисля, че проблемът ви е, че съхранявате препратки към елементите от списъка зле, може да искате да проверите това... забавлявайте се! (:   -  person    schedule 24.08.2013


Отговори (1)


Обикновено не е добра идея да съхранявате данните си в потребителския интерфейс.

Алтернативен отговор за това как бихте искали да организирате това:

  1. Съхранявайте списъка си с потребители в бизнес слоя на вашия проект.
  2. Показвайте потребителите, като използвате изглед на списък с виртуален модел, който получава данните от бизнес слоя. Вижте например отговора на https://stackoverflow.com/a/4233875/29290
  3. Достъп до тези данни по безопасен начин (заключване и т.н.)
  4. В нишката на Indy 10 достъпвайте данните по безопасен начин (заключване и т.н.)
  5. Накарайте бизнес слоя да уведоми частите Indy и UI за промени в данните
person Jeroen Wiert Pluimers    schedule 24.08.2013