Mam program, który używa wątku, który wykonuje trochę pracy. Wątek powinien powiadomić inny wątek (w tym przykładzie główny wątek) postępu.Obsługa zmiennej lokalnej w anonimowej procedurze przekazanej do TThread.Queue
Jeśli używam Synchronizuję(), aby wykonać synchronizację, wszystko działa zgodnie z oczekiwaniami. Gdybym synchronizacji z głównego wątku i publikują zmiennej dla i umieścić go na liście każda pojedyncza wartość get drukowane prawidłowo w moim ListBox:
procedure TWorkerThread.Execute;
var
i: Integer;
begin
inherited;
for i := 1 to 1000 do
begin
Synchronize(
procedure()
begin
FireEvent(i);
end);
end;
end;
Wyjście: 1, 2, 3, 4, 5. .. 1000
Jeśli użyć kolejki() w celu przeprowadzenia synchronizacji wyjściowe nie są, jak oczekiwano,
procedure TWorkerThread.Execute;
var
i: Integer;
begin
inherited;
for i := 1 to 1000 do
begin
Queue(
procedure()
begin
FireEvent(i);
end);
end;
end;
wyjściowa: 200, 339, 562, 934, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, [...]
Co się tutaj dzieje? Z mojego rozumienia anonimowa procedura powinna uchwycić zmienną "i"?
PS: Wiem, że nie ma sensu aktualizować interfejsu użytkownika tak często. Chcę tylko wiedzieć, co zmienia zmienną zawartość, mimo że metoda anonimowa powinna przechwycić wartość. –
Przechwytujesz zmienną. Ale próbujesz uchwycić "wartość". Musisz więc utworzyć nową zmienną, po jednej dla każdej iteracji pętli i przechwycić ją. To wymaga nowej ramki stosu, a zatem wywołania funkcji. Co prowadzi do kodu w odpowiedzi LURD. –