Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.06.2016, 18:36   #1
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию процедура странно работает

добрый день, есть код, так я веду отчет сколько раз ко мне подключался конкретный клиент

hash для каждого клиента уникален, это чт ото вроде идентификатора
Код:
Procedure DetaliseClientAddConnect(hash:String);
var
i:Integer;
add_cleint:Boolean;
begin

add_cleint:=true;
for I := 0 to logform.DetaliseClintC.Items.Count-1 do
    if logform.DetaliseClintC.Items.Item[i].Caption=hash then
    begin

        logform.DetaliseClintC.Items.Item[i].SubItems.Strings[0]:=inttostr(strtoint(logform.DetaliseClintC.Items.Item[i].SubItems.Strings[0])+1);
         add_cleint:=false; //не создаю запись а добавляю к имеющейся
         break;
    end;

 if add_cleint=true then {если не найдено такого ЦУ в списке}
   with logform.DetaliseClintC.Items.Add do
   begin
     caption:=hash;
     subitems.Add('1');
   end;


end;
в словах
при подключении пк к терминалу я ищу идентификатор(hash) данного пк в списке с отчетом, если такого идентификатора нет, создаю его и указываю что подключался один раз (считая это первое подключение раз не найден)
Если идентификатор (hash) все же найден, то увиличиваю число в subitems(1) на +1.


Все может работать нормально день, два... А иногда вижу вот такую картину
В теории, цифры помеченных синем цветом строк должны были приплюсовываться к выделенной строке
В связи с чем происходит добавление уже имеющейся строки? причем время от времени. значение hash - 100% неидентичны
Изображения
Тип файла: jpg Снимок.jpg (43.4 Кб, 144 просмотров)

Последний раз редактировалось aesoem; 20.06.2016 в 18:44.
aesoem вне форума Ответить с цитированием
Старый 21.06.2016, 21:10   #2
dmitriegorovih
Ещё не
Форумчанин
 
Аватар для dmitriegorovih
 
Регистрация: 04.01.2010
Сообщений: 517
По умолчанию

возможно проблема с потоками попробуйте завернуть через вот такое
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
end;
Воображение важнее, чем знания. (Albert Einstein)
dmitriegorovih вне форума Ответить с цитированием
Старый 22.06.2016, 17:15   #3
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию

Цитата:
Сообщение от dmitriegorovih Посмотреть сообщение
возможно проблема с потоками попробуйте завернуть через вот такое
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
end;

можно чуть подробнее? Synchronize(вызов процедуры)?

многопоточность я не использую в программе
aesoem вне форума Ответить с цитированием
Старый 22.06.2016, 18:00   #4
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

при реагировании на какое событие вызывается ваша процедура DetaliseClientAddConnect? сокеты работают в асинхронном режиме по событийной модели? другими словами, кто вызывает в коде метод DetaliseClientAddConnect?
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 22.06.2016, 19:58   #5
dmitriegorovih
Ещё не
Форумчанин
 
Аватар для dmitriegorovih
 
Регистрация: 04.01.2010
Сообщений: 517
По умолчанию

Цитата:
Сообщение от aesoem Посмотреть сообщение
можно чуть подробнее? Synchronize(вызов процедуры)?

многопоточность я не использую в программе
Дело в том что событие которые вызывает данную процедуру является не потокобезопасным поэтому в том месте где вы вызываете процедуру обверните её вот так
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
DetaliseClientAddConnect(hash:String);
end;
Есть мысля что программа из разных мест пытается получить доступ к компоненту и в определенных случаях не получает его, а возвращает пустой список. Что бы проверить это нужно жёстко залогировать все.
Воображение важнее, чем знания. (Albert Einstein)
dmitriegorovih вне форума Ответить с цитированием
Старый 22.06.2016, 20:29   #6
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию

Цитата:
Сообщение от dmitriegorovih Посмотреть сообщение
Дело в том что событие которые вызывает данную процедуру является не потокобезопасным поэтому в том месте где вы вызываете процедуру обверните её вот так
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
DetaliseClientAddConnect(hash:String);
end;
Есть мысля что программа из разных мест пытается получить доступ к компоненту и в определенных случаях не получает его, а возвращает пустой список. Что бы проверить это нужно жёстко залогировать все.
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
logunit.DetaliseCenterAddConnect(temp.Strings[1]);
end;
[dcc32 Error] DataUnit.pas(275): E2029 ')' expected but ';' found

я что-то не допечатал?) плаваю я в потоках...

Последний раз редактировалось aesoem; 22.06.2016 в 20:39.
aesoem вне форума Ответить с цитированием
Старый 22.06.2016, 20:31   #7
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию

Цитата:
Сообщение от 3D Hunter Посмотреть сообщение
при реагировании на какое событие вызывается ваша процедура DetaliseClientAddConnect? сокеты работают в асинхронном режиме по событийной модели? другими словами, кто вызывает в коде метод DetaliseClientAddConnect?
serversocket,событие onRead
aesoem вне форума Ответить с цитированием
Старый 22.06.2016, 20:33   #8
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию

Код:
procedure TData.TerminalToCenterClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
temp,otvet : tstrings;
i : integer;
begin

temp:=tstringlist.Create;
otvet:=tstringlist.Create;
temp.Text:=socket.ReceiveText;
TRY


if temp.Strings[0]='[hash]' then //получен хеш новое соединение
  begin
       {поиск всех клиентов данного центра и обнуление счетчика отпавки в сон}
  for I := 0 to mainform.ClientList.Items.Count-1 do
    if mainform.ClientList.Items.Item[i].SubItems.Strings[0]=temp.Strings[1] then
    mainform.ClientList.Items.Item[i].SubItems.Strings[6]:=inttostr(Optinsform.TimeOutEdit1.Value*60); //обнуляю время ожиданяи сервера до уъода вспчку


    {обновление иноформации об данном цу}
  for I := 0 to mainform.CenterList.Items.Count-1 do
  if mainform.CenterList.Items.Item[i].Caption=socket.RemoteAddress+':'+inttostr(socket.Handle) then
      begin
        mainform.CenterList.Items.Item[i].SubItems.Strings[0]:=temp.Strings[1];
        mainform.CenterList.Items.Item[i].SubItems.Strings[1]:=temp.Strings[2];

        if License.ACtivation(temp.Strings[1])<>'-1' then
        mainform.CenterList.Items.Item[i].ImageIndex:=1 else   mainform.CenterList.Items.Item[i].ImageIndex:=0;

      end;


      //высылаю в ответ список кмов согласно текущему хешу!

  for I := 0 to mainform.ClientList.Items.Count-1 do
    if mainform.ClientList.Items.Item[i].SubItems.Strings[0]=temp.Strings[1] then
      begin //найден км, отправляю его в центр управления
         otvet.Clear;
         otvet.Add('[next_client]');//идентификатор пакета
         otvet.Add(mainform.ClientList.Items.Item[i].Caption);//данные как связатся терминалу именно с данным клиентом
         otvet.Add(mainform.ClientList.Items.Item[i].SubItems.Strings[1]);//кол-во ядер
         otvet.Add(mainform.ClientList.Items.Item[i].SubItems.Strings[2]);//архитектура цп
         otvet.Add(mainform.ClientList.Items.Item[i].SubItems.Strings[3]);//майнер установлен какой
         otvet.Add(mainform.ClientList.Items.Item[i].SubItems.Strings[4]);//его статус
         otvet.Add(mainform.ClientList.Items.Item[i].SubItems.Strings[5]);//с каким параметром запущен
         if socket.Connected then

         socket.SendText(otvet.Text);

         sleep(500);
      end;

TThread.Synchronize(TThread.CurrentThread,procedure
begin
logunit.DetaliseCenterAddConnect(temp.Strings[1]);
end;


  end
       else
{РЕЖИМ ПЕРЕАДРЕСАЦИИ ОТ ЦЕНТРА УПРАВЛЕНИЯ КЛИЕНТУ}
{состав пакета}
//0: Неизвестный ТЕРМИНАЛУ идентификатор комманды в квадратных скобках
//1: уникальный номер центра управления hash (для того чтобы знать кому ответить)
//2: идентификатор подключения клиентского модуля

   for  I := 0 to mainform.ClientList.Items.Count-1 do
   if ((mainform.ClientList.Items.Item[i].Caption=temp.Strings[2]) and (TerminalToClient.Socket.Connections[i].Connected)) then
       begin
       TerminalToClient.Socket.Connections[i].SendText(temp.Text);
       logform.Memo1.Lines.Add('переадресован пакет в КМ:');
       logform.Memo1.Lines.Add('Клиент: '+temp.Strings[2]);
       logform.Memo1.Lines.Add('пакет: ');
       logform.Memo1.Lines.Add(temp.Text);
       end;




logform.Memo1.Lines.Add(temp.Text);


EXCEPT
END;
 otvet.Free;
temp.Free;
end;
aesoem вне форума Ответить с цитированием
Старый 22.06.2016, 20:44   #9
dmitriegorovih
Ещё не
Форумчанин
 
Аватар для dmitriegorovih
 
Регистрация: 04.01.2010
Сообщений: 517
По умолчанию

Цитата:
Сообщение от aesoem Посмотреть сообщение
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
logunit.DetaliseCenterAddConnect(temp.Strings[1]);
end;
[dcc32 Error] DataUnit.pas(275): E2029 ')' expected but ';' found

я что-то не допечатал?) плаваю я в потоках...
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
logunit.DetaliseCenterAddConnect(temp.Strings[1]);
end);
Воображение важнее, чем знания. (Albert Einstein)
dmitriegorovih вне форума Ответить с цитированием
Старый 22.06.2016, 23:18   #10
aesoem
Форумчанин
 
Регистрация: 24.12.2007
Сообщений: 288
По умолчанию

Цитата:
Сообщение от dmitriegorovih Посмотреть сообщение
Код:
TThread.Synchronize(TThread.CurrentThread,procedure
begin
logunit.DetaliseCenterAddConnect(temp.Strings[1]);
end);
спасибо, откорректировал свой код, часа 3 полет нормальный... глянем что к утру будет)
aesoem вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странно работает цикл while pr1me222 PHP 8 27.04.2014 01:06
WPF. странно работает тригер D][mon WPF, UWP, WinRT, XAML 1 28.11.2012 09:41
Странно работает Intel HD Graphics Serkoll Компьютерное железо 3 11.10.2012 15:34
БД Interbase работает странно. Yo_Asakyra БД в Delphi 1 27.05.2012 23:58
странно работает RegSetValueEx di91 Win Api 4 07.11.2010 15:27