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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.08.2010, 10:40   #1
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию Полтергейст в поточных переменных

Самопроизвольное изменение переменной потока - дурь какая-то:
есть поток:

Код:
unit UTH_TASK_Read;

interface

uses
  Windows, Classes, SysUtils,IdException, IdHTTP, UVar;



type
  TH_TASK_Read = class(TThread)
  protected
  Counter      : Integer;
  HTTP_TASK    : TidHTTP;
  Task_temp    : array of UVar.Task_Element;

  procedure Task_ok ();
  private
  TLoaded  : Boolean;
  function  Get_Len_Task  :Integer;
  function  Get_Ready  :Boolean;
  function  Get_Task(pos:Integer) : UVar.Task_Element;
  public
    Tasks        : array of UVar.Task_Element; // Запросы на действие SQL
    property Task [Pos:Integer] : UVar.Task_Element read  Get_Task;
    property Count        : integer read  Counter;
    property Len_of_task  : integer read  Get_Len_Task;
    property Task_Ready  : Boolean read  Get_Ready;
    procedure Execute; override;
    procedure GoNext;
  end;

implementation

uses UMain, UPin, ULog;

procedure TH_TASK_Read.Execute;
var
temp_str  : string;
tp        : Integer;
tv        : Integer;
P,L      : Integer;
sub_Input : String;
begin
  Counter:=0;
  TLoaded:=False;
  HTTP_TASK:= TidHTTP.Create(nil);
  HTTP_TASK.Request.BasicAuthentication:=UVar.SetI.Ini_SQL_Auth;
  if (UVar.SetI.Ini_SQL_Auth) then
  begin
  HTTP_TASK.Request.Username:=SetI.Ini_SQL_UserName;
  HTTP_TASK.Request.Password:=SetI.Ini_SQL_Password;
  end else
  begin
  HTTP_TASK.Request.Username:='';
  HTTP_TASK.Request.Password:='';
  end;

  while ((terminated=False) and (TLoaded=False)) do
  begin
  Inc(Counter);
    try
      If HTTP_TASK.Connected then HTTP_TASK.Disconnect();
      temp_str:='';
      temp_str:=HTTP_TASK.Get(URL_TAS_Get);
    except
    on E: EIdException do
    begin
      ULog.ErGO(1,'SQL_ASK_1','NET ERR: ' + E.Message);
    end;
    on E: Exception do
    begin
    ULog.ErGO(1,'SQL_ASK_2','NET ERR: ' + E.Message);
    end;
  end;
  If trim(temp_str)<>'' then
    begin
  while pos(#13,temp_str)>1 do
  begin
    p:=pos(#13,temp_str);
    sub_Input:=copy(temp_str,0,p-1);

    L:=Length(Task_temp);
    SetLength(Task_temp,L+1);

    tv:=1;
    while ((pos('|',sub_Input)>1) and (tv<5)) do
      begin
      tp:=pos('|',sub_Input);
      case tv of
        1 :  Task_temp[L].Key_Task  :=StrToInt(copy(sub_Input,0,tp-1));
        2 :  Task_temp[L].Key_Pin  :=StrToInt(copy(sub_Input,0,tp-1));
        3 :  Task_temp[L].Act      :=StrToInt(copy(sub_Input,0,tp-1));
        4 :  Task_temp[L].NewPos    :=StrToInt(copy(sub_Input,0,tp-1));
      end;
      inc(tv);
      if tv<5 then delete(sub_Input,1,tp);
      end;
    delete(temp_str,1,p);
  end;
If  Length(Task_temp)>0 then
      begin
        Synchronize(Task_ok);
      end;
      end;

    Sleep(200);
  end;
  HTTP_TASK.Free;
end;


function TH_TASK_Read.Get_Len_Task():Integer;
begin
  Result:=Length(Tasks);
end;

function  TH_TASK_Read.Get_Task(pos:Integer):UVar.Task_Element;
begin
Result:=Tasks[pos];
end;

procedure TH_TASK_Read.GoNext;
begin
TLoaded:=False;
SetLength(Tasks,0);
end;

procedure TH_TASK_Read.Task_ok();
var
l: Integer;
x: Integer;
begin
l:=Length(Task_temp);
SetLength(Tasks,l);
for x := 0 to L - 1 do
begin
Tasks[x].Key_Task  :=Task_temp[x].Key_Task;
Tasks[x].Key_Pin  :=Task_temp[x].Key_Pin;
Tasks[x].Act      :=Task_temp[x].Act;
Tasks[x].NewPos    :=Task_temp[x].NewPos;
Tasks[x].Command  :=Task_temp[x].Command;
end;
  TLoaded:=True;
end;

function  TH_TASK_Read.Get_Ready  :Boolean;
begin
  Result:= TLoaded;
end;
end.
есть процедура, которая обрабатывает приходящее из потока:



Код:
.
.

  private
    { Private declarations }
      BUS_READ_th : TH_BUS_Read;    // Поток BUS_READ
      TASK_READ_th : TH_TASK_Read; // Поток BUS_READ
    procedure Data_Arrival(var Msg: TMessage); message mes_BUS_READ_Data_Arrival;
  public
    { Public declarations }
    TASK_All : Array of Uvar.Task_Element;
  end;
.
.


....
SetLength(TASK_ALL,0);
if TASK_READ_th.Task_Ready then
begin
  trl:=TASK_READ_th.Len_of_task;
  tal:=Length(TASK_ALL);
  SetLength(TASK_ALL,trl+tal);
  for tc := 0 to trl - 1 do
  begin
  one_task:=TASK_READ_th.Task[tc];
    TASK_ALL[tal+tc].Key_Task :=one_task.Key_Task;
    TASK_ALL[tal+tc].Key_Pin  :=one_task.Key_Pin;
    TASK_ALL[tal+tc].Act      :=one_task.Act;
    TASK_ALL[tal+tc].NewPos  :=one_task.NewPos;
    TASK_ALL[tal+tc].Command  :=one_task.Command;
  end;
  TASK_READ_th.GoNext; // Сбрасываем флаг, для дальнейшего запроса тасков.
end;
....
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 10:40   #2
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

В потоке описана пропертия ))): property Task_Ready : Boolean read Get_Ready;
Которая при наличии данный ставится потоком в True, после того, как основное приложение данные вытащит себе - оно через процедуру потока ставит эту переменную в False и по идее все начинается сначала. (Кроме самих функций потока, НИЧЕГО не изменяет эту флаговую переменную, и она изменяется 1 раз при приходе данных, 1 раз когда данные обработаны).

Так вот- происходит полный полтергейст в моем понимании- данные приняли, флаг поставили в 1, основной процесс увидел, данные высосал, сбросил флаг, но через несколько циклов основной программы - флаг на ровном месте опять TRUE!!!!
И тут армагедец!!!!!!!!! данных то нетю, exption'ы и прочая ))))


С чего?????????????
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 10:46   #3
ex.cluz
Участник клуба
 
Аватар для ex.cluz
 
Регистрация: 15.01.2010
Сообщений: 1,325
По умолчанию

Хм. А где sinhronize?
Или он тут и не нужен?
Грибы - они разные. Один тебя накормит, другой тебе кино покажет...
Редактор журнала "
[ПРОграммист]"
Yan's Home Digital Lab
ex.cluz вне форума Ответить с цитированием
Старый 30.08.2010, 10:49   #4
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

А зачем sinhronize? Я по приему меняю переменную внутри потока.
А по выкусыванию данных основным приложением - меняю обратно опять же через функцию потока.

По секрету - пробовал и с ним.
Что с ним, что без - в дебагере смотришь - сделай флаг 1 -> флаг 1, сделай флаг 0 - флаг 0, бац флаг 1.
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 11:16   #5
ex.cluz
Участник клуба
 
Аватар для ex.cluz
 
Регистрация: 15.01.2010
Сообщений: 1,325
По умолчанию

Может, там с адресным пространством чего...попробуйте, переменную булеву в главном потоке использовать (это кривовато, но попробывать можно).
А что за компиллятор?

Кстати, а чем suspend не подходит?
Грибы - они разные. Один тебя накормит, другой тебе кино покажет...
Редактор журнала "
[ПРОграммист]"
Yan's Home Digital Lab

Последний раз редактировалось ex.cluz; 30.08.2010 в 11:23.
ex.cluz вне форума Ответить с цитированием
Старый 30.08.2010, 11:25   #6
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

CodeGear Delphi 2009 12.0...
Лезть из дочернего потока в основной за флагом? Даже на слух "неправильная" идея, но надо попробовать )))
А с адресным пространством чего может быть, пусть в принципе?
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 11:45   #7
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

suspend пробовал - с ним работает, хочется чтобы поток запустил и забыл, он висит и с заданной периодичностью данные принимает...
а suspend/resume перезапускают поток или поток продолжает c места суспенда?
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 13:13   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

У вас поток пишет в свои свойства. Форма из них читает. А синхронизировать это кто будет?

Сейчас у вас Task_ok засунута в Synchronize - зачем?

А для флага - ну так поставьте на него бряк (Memory breakpoint), всего делов-то.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 30.08.2010, 13:23   #9
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
У вас поток пишет в свои свойства. Форма из них читает. А синхронизировать это кто будет?

Сейчас у вас Task_ok засунута в Synchronize - зачем?

А для флага - ну так поставьте на него бряк (Memory breakpoint), всего делов-то.
Task_ok - как раз и поднимает флаг, как раз внутри Synchronize для синхронизации с основным потоком.
termsl вне форума Ответить с цитированием
Старый 30.08.2010, 13:26   #10
termsl
 
Регистрация: 30.08.2010
Сообщений: 8
По умолчанию

Как (Memory breakpoint) поставить, между делом?
termsl вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Видимость переменных tae1980 Microsoft Office Excel 3 26.03.2009 18:34
Много переменных Altera Общие вопросы Delphi 15 18.07.2008 08:06
Чистка переменных delphin100 Общие вопросы Delphi 9 30.06.2008 10:53
Вальс переменных Иллидан Общие вопросы Delphi 9 27.01.2008 10:39
Замена переменных NoName_emaNoN Win Api 4 18.01.2008 09:05