在主线程上下文中执行代码 (Lazarus)
我必须在主线程的上下文中执行一些代码。我使用的是Lazarus + FPC。我从 DLL(如果在 Linux 上是共享库)内的线程接收到一个事件,并且我的回调函数被调用。请注意,此函数不是任何类的成员,而是附加了“cdecl”指令的独立传统函数。
我必须为收到的每条此类消息触发一个相应的属性事件处理程序。而这些事件必须在主线程的上下文中传递。我知道两个这样的解决方案:
- PostMessage
- Application.QueueAsyncCall
第一个可以,但它需要一个窗口句柄。由于这是一个库代码,因此没有可用的句柄。 AllocateHWND 不是一个选项,因为它不是跨平台的。我知道我可以创建一个虚拟表单,但这是一个非常糟糕的解决方案
第二个工作正常,但我有一个问题,例如,直到我在应用程序内移动鼠标后才会处理调用。也许我做错了什么我不知道。我就像只有在消息处理开始时才处理我的呼叫。但这显然可能是一个漫长的等待。
所以我想知道这里最好的解决方案是什么(可能是 QueueAsyncCall)以及如何确保我的消息(调用)将在可接受的时间范围内得到处理?
I have to execute some code in the context of the main thread. I am using Lazarus + FPC. I receive an event from a thread inside a DLL (shared library if on linux) and my callback function gets called. Note that this function is not a member of any class but a standalone traditional function with a "cdecl" directive attached.
I have to triger a coresponding property event handler for each such message I receive. And these events have to be passed on in the context of the main thread. I know of two such solutions:
- PostMessage
- Application.QueueAsyncCall
The first one is ok, but it requires a window handle. And since this is a library code no handle is available. AllocateHWND is not an option since it is not cross platform. I know I can create a dummy form but this is a very bad solution
The second works ok, but I have a problem, that the call is not processed until I move a mouse inside application for instance. Maybe I am doing something wrong I don't know. I is just like my call is being processed only when message processing kicks in. But this can be a long wait apparently.
So I want to know what is the best solution here (probably QueueAsyncCall) and how I can be sure that my message (call) will be processed in acceptable timeframe?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您无法 100% 确定,就像在任何非实时系统中一样。如果主线程挂起,它不会检查主循环中的消息或其他事件。这是正常的。
你唯一能做的就是避免在主线程中做一些可能需要很长时间的事情。准确判断什么是必要的、什么不是必要的,这是行业的技巧。一些面向实时的人将所有文件系统访问移至线程,并严格保留 GUI 用于 UI,只是因为如果用户为此或另一个配置网络共享上的路径,则共享问题很容易导致长时间超时等待,甚至几分钟。
如果我查看 application.queueasynccall,我会发现没有线程安全处理(没有锁定或锁定队列),因此其中一个已被排除。
我知道 Lazarus 在非 Windows 上在某种程度上模拟了 postmessage,我检查了实现,它确实有锁,所以我认为它是多线程安全的。
You can not be 100% sure, just like you can't in any non-realtime system. If the mainthread hangs, it won't check for messages or other events in the main loop. This is normal.
The only thing you can do is to avoid doing stuff in the mainthread that can take a long time. It's the trick of the trade to exactly judge what is necessary and what is not. Some realtime oriented people move all filesystem access to threads, and keep the GUI strictly for UI, just because if an user configures a path on a network share for this or the other, a problem with the share can easily cause a long timeout wait, of minutes even.
If I look at application.queueasynccall, I see no threadsafe processing (no locking or locked queues), so that one is out.
I know postmessage is emulated by Lazarus to some degree on non Windows, and I checked the implementation and it does have lock, so I assume it is multithreading safe.