Dziwne problemy z watkiem :/

0

Witam. Mam procedure, ktora duzo liczy i w trakcie tej czynnosci aplikacja jest zamrozona. Jak umeiszcze wewnatrz application.processmessages to juz nie jest zamrozona, ale duzo zwalniaja obliczenia. Pomyslalem, ze umieszcze w takim razie Applicatio.ProcessMessages w watku i bede wywolywal co 250ms, ale to nie dziala :( Watek sie wykonuje, ale efektow przetworzenia wiadomosci nie widac :-/ To jedno, a drugie to pomimo, ze robie Watek.Terminate to sie nie zamyka.

procedure TWatek.Execute;
begin
  FreeOnTerminate := True;
  while not (Application.Terminated) or (Terminated) do begin
    Application.ProcessMessages;
    Sleep(250);
  end;
end;
0

To właśnie w wątku powinienieś prowadzić obliczenia, a w wątku głównym ewentualnie zajmować się interfejsem. Wątek w ogóle nie powinien dotykać obiektu Application.

0

No niestety procedura liczaca jest bardzo skomplikowana, ma wiele powiązań z interfejsem i musi mieć, więc co proponujesz?

0

Tak jak powiedział Szczawik, jeśli potrzebujesz szybkich obliczeń nie odwołuj się do Formy. Jakiekolwiek odwołanie się do jakiegoś obiektu strasznie spowalnia obliczenia. Najgorzej, gdy wpadnie Ci do głowy pomysł pokazywania na formie wyniku aktualnych obliczeń!!! Jeśli już bardzo tego potrzebujesz, użyj timerów i aktualizuj formę, co sekundę czy kilka.

Proponuję przepisać do threada dane z Aplikacji, wykonać na nich obliczenia i dopiero na końcu przepisać wynik. Z własnego doświadczenia wiem, że powiedzmy wpisywanie do obiektu "Edit" jakiejś wartości z wyliczanych aktualnie danych nie tylko spowolni process, ale może wywołać śliczne exception (nawet synchronize tu nie pomoże).

:P

0

kolejkę wiadomości obsługuje ten wątek, który stworzył okno do którego przychodzą komunikaty, w Twoim wypadku główny wątek - proces - aplikacji. stąd Twój problem. może gdybyś spróbował wywołać processmessages w kontekście głównego wątku (snchronize) dało by to jakiś rezultat, ale wątpię, żeby się dało, skoro główny wątek jest już zajęty obliczeniami.

0

Skoro interfejs ma zastój bo wątek obliczeniowy ma powiązania z wątkiem głównym, znaczy, że w czasie obliczeń user tylko czeka i nic nie wprowadza - sytuacja idealna - przed rozpoczęciem obliczeń przekaż obliczeniowemu (CreateSuspended) wszystkie potrzebne dane i dopiero wystartuj obliczenia (Resume), a główny może sobie chodzić jak chce. Obliczeniowy w swoim OnTerminate przekaże wyniki działań i po sprawie (OnTerminate jest już wykonywane w ramach głównego wątku, więc nie bedzie problemów z wielodostępem).

0

Dobra dzięki, jutro napisze co zmajstrowałem ;)

0

Można ustawić priorytet na najniższy (IDLE_PRIORITY_CLASS)

1 użytkowników online, w tym zalogowanych: 0, gości: 1