TThread с обичайно OnTerminate поведение

Четох тази публикация, която почти реши проблема ми, тъй като никой не отговори на коментарите ми, реших да задам въпрос:

Оригинална публикация, която почти отговаря на въпроса ми

Както попитах там:

  • Тъй като е възможно множество нишки да споделят едно и също OnTerminate събитие, възможно ли е също да завършат по едно и също време?
  • Ако е така, какво се случва? Извикването на метода OnTerminate ще бъде "поставено в опашка" от операционната система? С други думи, кодът ще бъде ли свободен от повторно влизане, ако използва MainThread свойства?

person EProgrammerNotFound    schedule 25.07.2013    source източник


Отговори (2)


Възможно е множество нишки да споделят едно и също събитие OnTerminate

Да, точно както ви показа отговорът на другия въпрос.

и да завършите едновременно?

Нишките може да завършат работата си по едно и също време, но по подразбиране манипулаторът(ите) на събитие OnTerminate няма да бъде извикан едновременно. Това е така, защото манипулаторът на събития OnTerminate се задейства от TThread с помощта на вътрешно извикване към TThread.Synchronize(), така че множество нишки, задействащи своите OnTerminate събития едновременно, няма да се припокриват. За да промените това поведение (което повечето хора не правят), ще трябва да замените виртуалния TThread.DoTerminate() метод, за да извикате ръчно директно манипулатора на събития OnTerminate, без първо да извикате TThread.Synchronize().

person Remy Lebeau    schedule 25.07.2013
comment
Не, няма да отменя, това поведение е наред - person EProgrammerNotFound; 25.07.2013
comment
@MartinJames Ще приема отговора на Реми, защото той отговори пръв и обясни synchronize поведението, ок? отговорът ви беше много ясен и полезен. Благодаря ви, момчета, за цялата оказана помощ, благодаря на @Martin за подсказката Application.ProcessMessages - person EProgrammerNotFound; 25.07.2013

OnTerminate е събитие, задействано във VCL нишката, така че ще е било PostMessaged или, по-вероятно, SendMessaged. Така или иначе, OnTerminates ще бъдат сериализирани.

Въпреки това, никога не съм използвал това събитие от D3 (когато разбрах колко от поддръжката на нишки на Delphi всъщност „работи“).

Редактиране - може би можете да накарате вашите OnTerminate обаждания да влязат отново, като извикате Application.ProcessMessages в него (ако се чувствате особено склонни към самоубийство:).

person Martin James    schedule 25.07.2013
comment
Това събитие подслушва ли се? - person EProgrammerNotFound; 25.07.2013
comment
В delphi 6, както каза @Remy, той използва syncrhonize вместо SendMessage - person EProgrammerNotFound; 25.07.2013
comment
you can maybe get your OnTerminate calls to reenter by calling Application.ProcessMessages Истина [+1]. - person EProgrammerNotFound; 25.07.2013
comment
Е, да и не. Нека просто кажем, че е отворен за злоупотреба. TThread.Synchronize (методът на Delphi, който обвива комуникациите между нишките на операционната система, необходими, за да работи), е преработен няколко пъти. Обикновено успявам да избегна TThread.OnTerminate, като никога не прекратявам изрично TThreads. - person Martin James; 25.07.2013
comment
Хммм, можете ли да ми дадете пример за злоупотреба за бъдещи справки? - person EProgrammerNotFound; 25.07.2013
comment
@MatheusFreitas да, и TThread.Synchronize използва или SendMessage, или APC на опашка. - person Martin James; 25.07.2013
comment
@MatheusFreitas: TThread винаги е използвал Synchronize() за извикване на манипулатора на събития OnTerminate. В Delphi 5 и по-рано Synchronize() използваше само SendMessage(). В Delphi 6 (когато беше представен Kylix), Synchronize() беше пренаписан, за да използва вместо това глобален списък от указатели на методи и след това използва PostMessage() за събуждане на основната нишка. Основната нишка периодично извиква CheckSynchronize(), за да премине през този списък, извиквайки чакащите методи. - person Remy Lebeau; 25.07.2013
comment
Е, единственият проблем, който виждам, е ако потребителят не проверява прекратено в контекста на изпълнението, също, ако някой спре и освободи нишката, но както казахте, че това е злоупотреба, няма да направя това никога. Много благодаря - person EProgrammerNotFound; 25.07.2013