Я экспериментирую с многопоточностью в Delphi (XE) и столкнулся с проблемой использования глобальной переменной между основным потоком VCL и вторым рабочим потоком.
Мой проект включает в себя второй рабочий поток, который просматривает некоторые файлы и обновляет строку globalvar с включенным текущим именем файла. Этот globalvar затем выбирается с помощью таймера в главном потоке VCL и обновляет строку состояния.
Однако я заметил, что иногда возникает «недопустимая операция указателя» ... или «недостаточно памяти», или рабочий поток просто перестает отвечать (вероятно, тупик).
Поэтому я создал тестовое приложение, чтобы идентифицировать и значительно увеличить вероятность ошибки, чтобы я мог видеть, что происходит.
type
TSyncThread = class(TThread)
protected
procedure Execute; override;
end;
var
Form11: TForm11;
ProgressString : String;
ProgressCount : Int64;
SyncThread : TSyncThread;
CritSect : TRTLCriticalSection;
implementation
{$R *.dfm}
procedure TForm11.StartButtonClick(Sender: TObject);
begin
Timer1.Enabled := true;
SyncThread := TSyncThread.Create(True);
SyncThread.Start;
end;
procedure TForm11.StopbuttonClick(Sender: TObject);
begin
Timer1.Enabled := false;
SyncThread.Terminate;
end;
procedure TForm11.Timer1Timer(Sender: TObject);
begin
StatusBar1.Panels[0].Text := 'Count: ' + IntToStr(ProgressCount);
StatusBar1.Panels[1].Text := ProgressString;
end;
procedure TSyncThread.Execute;
var
i : Int64;
begin
i := 0;
while not Terminated do begin
inc(i);
EnterCriticalSection(CritSect);
ProgressString := IntToStr(i);
ProgressCount := i;
LeaveCriticalSection(CritSect);
end;
end;
initialization
InitializeCriticalSection(CritSect);
finalization
DeleteCriticalSection(CritSect);
Я установил интервал таймера на 10 мс, чтобы он много читал, пока рабочий поток не работает, обновляя глобальную строку var. Конечно, это приложение едва длится секунду при запуске, прежде чем оно появляется с вышеуказанными ошибками.
Мой вопрос: нужно ли запускать операцию чтения Global var в VCL Timer в критическом разделе? - если так, то почему? Насколько я понимаю, это только чтение, и с записями, уже запущенными в критическом разделе, я не могу понять, почему он сталкивается с проблемой. Если я помещаю чтение в таймере также в критическую секцию - это работает нормально .... но я недоволен, просто делая это, не зная, почему!
Я новичок в многопоточности, поэтому был бы признателен за любую помощь в объяснении, почему этот простой пример вызывает все виды проблем и если есть лучший способ получить доступ к строке из рабочего потока.
multithreading,delphi,delphi-xe,