代码之家  ›  专栏  ›  技术社区  ›  Runner

在主线程(Lazarus)上下文中执行代码

  •  4
  • Runner  · 技术社区  · 14 年前

    我必须在主线程上下文中执行一些代码。我用的是拉撒路+FPC。我从一个动态链接库(在Linux上是共享库)内的线程接收到一个事件,然后调用回调函数。请注意,此函数不是任何类的成员,而是附加了“cdecl”指令的独立传统函数。

    我必须为收到的每一条这样的消息触发一个共同响应的属性事件处理程序。这些事件必须在主线程上下文中传递。我知道有两种解决办法:

    1. 发送消息
    2. application.queueAsyncCall应用程序

    第一个可以,但它需要一个窗口句柄。因为这是一个库代码,所以没有可用的句柄。allocateHwnd不是一个选项,因为它不是跨平台的。我知道我可以创建一个虚拟表单,但这是一个非常糟糕的解决方案

    第二个工作正常,但我有一个问题,即在我将鼠标移动到应用程序中之前,调用不会被处理。也许我做错了什么,我不知道。我就像我的呼叫只有在消息处理开始时才被处理。但显然,这可能需要很长时间的等待。

    因此,我想知道这里的最佳解决方案是什么(可能是QueueAsyncCall),以及如何确保在可接受的时间范围内处理消息(调用)?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Marco van de Voort    14 年前

    你不能100%肯定,就像你不能在任何非实时系统。如果mainthread挂起,它将不会检查主循环中的消息或其他事件。这是正常的。

    您唯一能做的就是避免在维护线程中执行可能需要很长时间的操作。准确判断什么是必要的,什么是不必要的,这是行业的诀窍。一些面向实时的人将所有文件系统访问权转移到线程上,并严格为用户界面保留GUI,这是因为如果用户为此或另一个在网络共享上配置路径,那么共享问题很容易导致长时间的超时等待,甚至几分钟。

    如果我看application.queueasyncCall,我看不到线程安全处理(没有锁定或锁定的队列),所以这个队列是不存在的。

    我知道Lazarus在某种程度上在非Windows上模拟了postmessage,我检查了实现,它确实有锁,所以我假设它是多线程安全的。