2010-08-26 5 views
4

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

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

  1. PostMessage
  2. Application.QueueAsyncCall

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

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

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

ответ

1

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

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

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

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

+0

Мне хорошо известно, что я не могу быть на 100% уверенным, но мое приложение ничего не делает, и все же вызовы не обрабатываются, пока я не двигаю мышь. Поэтому я лучше с PostMessage. Но недостатком является то, что AllocateHWND еще не реализован в кроссплатформенном виде. Или это? Я думал, что Application.QueueAsyncCall является потокобезопасным. Я проверю реализацию. Спасибо за ответ, хотя. У меня довольно много опыта в многопоточном окружении, но я довольно новичок в Lazarus. При этом проблемы :) – Runner

+0

Ужас :) Это trully ни в коем случае нитевое. Так что есть альтернатива обмену сообщениями, помимо PostMessage. Я имею в виду простой, без IPC или TCP/IP? – Runner

+0

Не совсем. Я предполагаю, что они понесли проблемы с реализацией эмуляции postmessage на других платформах по какой-то причине. –