TMutex.Acquire
- это обертка вокруг THandleObjects.WaitFor
, которая будет вызывать WaitForSingleObject
ИЛИ CoWaitForMultipleHandles
в зависимости от аргумента UseCOMWait
.
Это может быть очень важно, если вы используете COM-объекты STA в своем приложении (вы можете сделать это, не зная, например, dbGO / ADO - это COM), и вы не хотите тупиковать.
Все еще опасно вводить длительное / бесконечное ожидание в главном потоке, потому что единственный метод, который правильно обрабатывает вызовы, сделанные с помощью TThread.Synchronize
, это TThread.WaitFor
, и вы можете заблокировать (или заблокировать) свои рабочие потоки, если вы используете Объекты SyncObjs или функции ожидания WinAPI.
В коммерческих проектах я использую пользовательский метод ожидания, основанный на идеях обоих THandleObjects.WaitFor
И TThread.WaitFor
с необязательным ожидающим оповещением (хорошо для асинхронного ввода-вывода, но незаменимый для возможности прервать длинные ожидания).
Редактировать: дальнейшие разъяснения относительно COM / OLE:
В модели COM / OLE (например, ADO) могут использоваться разные модели резьбы: STA (однопоточная) и MTA (многопоточная или свободная).
По определению основной поток графического интерфейса инициализируется как STA, что означает, что COM-объекты могут использовать оконные сообщения для своего асинхронного обмена сообщениями (особенно при вызове из других потоков для безопасной синхронизации). AFAIK, они также могут использовать процедуры APC.
Существует веская причина существования функции CoWaitForMultipleHandles
- см. Ее использование в SyncObjs.pas THandleObject.WaitFor
- в зависимости от модели потоков, она может обрабатывать внутренние COM-сообщения, блокируя дескриптор ожидания.