Gunnman писал(а):
Запутался...
Если вызвать doSend из запущенного тобой параллельного потока, то главный поток в процессе doSend будет не занят и сможет выдавать событие onReceive одновременно с твоим doSend. Это и имелось в виду.
Gunnman писал(а):
Правильно я понимаю что главный поток - это поток который создается системой при запуске ПО
Да. При запуске приложения система создаёт один поток, и в нём выполняет код, расположенный по адресу, указанному в специальном месте исполняемого файла (называется "точка входа"). После отработки кода в этом месте приложение завершает работу (даже если запустило другие потоки - они принудительно останавливаются). Для того, чтобы приложение постоянно оставалось запущеным и выполняло команды пользователя, в главном потоке оно должно запустить цикл, ожидающий какого-либо условия для завершения своей работы, ну и команд от пользователя.
GUI ("оконное") приложение реализует в этом цикле с помощью функций Windows выборку оконных сообщений, передачу их на обработку созданным в этом приложении окнам. Обычно, этот цикл завершается, когда будет закрыто первое созданое приложением окно (а точнее, в очередь сообщений будет послано сообщение WM_QUIT). Если посмотреть исходный код проектов Delphi, то можно увидеть, что сначала создается главное окно, а затем вызывается процедура Application.Run(), содержащая такой цикл. А пользователь уже управляет приложением, используя элементы управления в главном и других окнах. Всё, что он нажимает в окнах, попадает в виде сообщения в главный цикл, тот передаёт его оконной процедуре окна, в котором оно произошло, а она ищет обработчик, назначенный программистом для данного сообщения (например, в панели событий Delphi IDE).
Gunnman писал(а):
У него так же есть задержка?
Если функция выборки очередного сообщения показывает, что сообщений нет, цикл вызывает специальную функцию, которая ждёт появления сообщения. То-есть, главный поток в этот момент ничего не делает. Когда появляется сообщение, поток возобновляет свою работу и идёт на следующую итерацию цикла обработки сообщений.
Gunnman писал(а):
В таймерах и компоненте Thread есть задержка между итерациями
Да, только их природа разная - в Thread это тупо цикл и функция Sleep(), а в Таймере, возможно, то же самое, только где-то в недрах системы, и каждая итерация сопровождается посылкой в наш главный цикл сообщения таймера. MMTimer отличается от простого Timer тем, что не шлёт оконных сообщений, а прямо вызывает нужное событие "в параллельном потоке". И этим он полностью по функционалу аналогичен нашему Thread с задержкой.