Если ваш так называемый «основной» поток получает критическую секцию, а затем поток VCL (что мы обычно называем «основным» потоком) пытается получить его, тогда VCL поток будет блокироваться, пока критический раздел не будет освобожден. Затем ваш «основной» поток вызывает Synchronize
, который выполняет данную функцию в контексте потока VCL. Поскольку поток VCL блокируется в ожидании критической секции, он не обрабатывает сообщения, поэтому он не может заметить, что существует синхронизированный метод для вызова. Таким образом, тупик.
Не удерживать блокировку между вызовами внутри потока. Освободите блокировку в «основном» потоке, прежде чем вызывать Synchronize
, а затем повторно запустите ее, если она вам все еще нужна. Если данные, используемые в синхронизированном методе, нуждаются в постоянной защите от одновременного доступа, то я думаю, что вы должны найти способ скопировать данных в отдельный, не общий объект. Пусть синхронизированный метод использует этот объект вместо общего, а затем уничтожит его.
Ваш комментарий означает, что вы можете вызвать функцию обратного вызова без Synchronize
, и все, кажется, работает. В этом случае синхронизированный метод не вызывается в том же контексте потока, что и раньше. Он вызывается непосредственно вашим "основным" потоком, а не потоком VCL. Это, очевидно, снимает конфликт блокировки, но действительно ли это безопасно, зависит от того, что делает функция обратного вызова.