Выполнить код в контексте основного потока (Lazarus) - PullRequest
4 голосов
/ 26 августа 2010

Я должен выполнить некоторый код в контексте основного потока.Я использую Lazarus + FPC.Я получаю событие из потока внутри DLL (разделяемой библиотеки, если в Linux), и вызывается моя функция обратного вызова.Обратите внимание, что эта функция не является членом какого-либо класса, но представляет собой отдельную традиционную функцию с присоединенной директивой "cdecl".

Мне нужно вызывать обработчик события свойства coresponding для каждого такого сообщения, которое я получаю.И эти события должны быть переданы в контексте основного потока.Я знаю два таких решения:

  1. PostMessage
  2. Application.QueueAsyncCall

Первое решение в порядке, но для него требуется дескриптор окна.А поскольку это код библиотеки, дескриптор недоступен.AllocateHWND не вариант, так как он не кроссплатформенный.Я знаю, что могу создать фиктивную форму, но это очень плохое решение

Второе работает нормально, но у меня есть проблема, что вызов не обрабатывается, пока я, например, не перемещаю мышь внутри приложения.Может быть, я делаю что-то не так, я не знаю.Я точно так же, как мой вызов обрабатывается только тогда, когда начинается обработка сообщения. Но, очевидно, это может быть долгим ожиданием.

Поэтому я хочу знать, какое решение лучше здесь (вероятно, QueueAsyncCall) и как я могубыть уверенным, что мое сообщение (звонок) будет обработано в приемлемые сроки?

1 Ответ

1 голос
/ 27 августа 2010

Вы не можете быть на 100% уверены, так же, как вы не можете в любой системе не в реальном времени.Если основная тема зависает, она не будет проверять сообщения или другие события в основном цикле.Это нормально.

Единственное, что вы можете сделать, - это избегать выполнения каких-либо действий в основной теме, что может занять много времени.Это уловка торговли, чтобы точно судить, что необходимо, а что нет.Некоторые люди, ориентированные на реальное время, перемещают весь доступ к файловой системе в потоки и строго поддерживают графический интерфейс для пользовательского интерфейса, просто потому, что если пользователь настраивает путь на общем сетевом ресурсе для того или другого, проблема с общим ресурсом может легко вызвать длительное ожидание,минут даже.

Если я посмотрю на application.queueasynccall, я не увижу поточно-ориентированной обработки (без блокировок или заблокированных очередей), так что одна из них отсутствует.

Я знаю, что пост-сообщение эмулируется Lazarus в некоторой степенине Windows, и я проверил реализацию, и она имеет блокировку, поэтому я предполагаю, что это многопоточность безопасна.

...