Synchronize()挂断线程 [英] Synchronize() hangs up the thread

查看:158
本文介绍了Synchronize()挂断线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Delphi中编写一个dll库,其中创建了多个线程。让我一步一步地描述问题。我很抱歉有一个冗长的描述: - (。



让我们忘记一段时间的图书馆,我创建了一个Windows应用程序,我创建了一个窗口,用于显示单个相机的视图,它包含一个TImage控件,有一个线程(一个TThread后代),每隔几毫秒从相机中下载当前图像,并将其分配给该窗口的TImage控件(使用Synchronize()方法)。应用程序在启动时创建该窗口的几个实例(每个实例都有一个单独的线程),因此您可以一次看到多个摄像机的实时视图。更重要的是,所有这些查看窗口都被主应用程序窗口所覆盖,因此它们显示在其中。



一切正常,直到我决定将这两个窗口放入dll库我刚刚发现有必要出于某些原因,但现在并不重要,所以我创建了一个新的dll lib将现有主窗口和摄像机视图窗口添加到项目中,并导出创建并返回主窗口实例的函数。当主窗口创建时,它会创建多个相机视图窗口,使其成为其父级。



然后,为了测试目的,我创建了一个导入上述提到的应用程序dll函数从库中调用,并在启动时获取主窗口的实例;然后在屏幕上显示(处于非模式状态)。



当我启动应用程序时,我发现我无法从任何相机获得单个图像。当我调试它,我注意到当线程调用Synchronize()方法时,它永久挂起。在把这两个窗口都放在一个dll之前没有发生。



这是我的问题。说实话,这是我到目前为止我不得不经历许多其他问题的图书馆的第一个方法。你可能会想知道为什么我使用Windows而不是框架...所以每当我在dll中创建一个TFrame的实例,我会得到一个例外,说控件xxx没有父窗口。我不知道该怎么做,所以我用windows替代: - (。



请问你能告诉我怎么处理同步问题?主线程似乎没有以任何方式阻止应用程序启动它接受点击按钮等。然后问题是什么?



请帮助!



提前谢谢!

解决方案

当您致电 TThread.Synchronize 线程和方法指针被添加到Classes.pas中的全局 SyncList:TList 。在主exe的例程调用 CheckSynchronize ,它检查 SyncList ,但它将检查exe中的版本,而不是DLL中的版本。最终结果,您的同步方法从不被调用。



最简单的修复是从DLL切换到包,这将消除重复的 SyncList



另一种方法是覆盖exe的 Application.OnIdle 回调,并手动调用您的DLL的 CheckSynchronize 。你需要一些应用程序的帮助,虽然,因为你的DLL也将有一个应用程序对象,那个将不起作用。


I'm writing a dll library in Delphi with multiple threads created by it. Let me describe the problem step by step. I'm sorry for a lengthy description in advance :-(.

Let's forget about the library for a while. I created a windows application that is going to present views from several cameras. I created a window which is meant to show the view from a single camera and it contains a TImage control. There is a thread (a TThread descendant) that downloads the current image from the camera every couple of milliseconds and assigns it to the TImage control of that window (using the Synchronize() method). The application creates several instances of that window on startup (with a separate thread for each of them), so you can see the live view from several cameras at once. What's more, all those viewing windows are parented by the main application window, so they appear within it.

Everything worked fine until I decided to put those two windows into a dll library. I just found it necessary for some reasons, but they are not important now. So I created a new dll library, added the existing main window and the camera-view window to the project and exported a function that creates and returns an instance of the main window. When the main window is created, it creates several camera-view windows, making itself their parent.

Then, for testing purposes, I created an app that imports the above mentioned dll function from the library and calls it at startup to get an instance of the main window; then just shows it on the screen (in a non-modal state).

When I started the app it came out that I couldn't get a single image from any camera then. When I debugged it, I noticed that when the thread calls the Synchronize() method, it hangs forever. It didn't happen before putting both those windows into a dll.

And this is my problem. To be honest, this is my first approach to libraries I have had to get through many other problems so far. You might wonder why I use windows instead of frames... So whenever I created an instance of a TFrame in a dll, I would get an exception saying "the control xxx does not have a parent window". I did not know what to do about that so I used windows instead :-(.

Could you please tell me what to do with the synchronization problem? The main thread does not seem to be blocked in any way when the application is started for it accepts clicking buttons etc. What is the problem then?

Please, help!

Thank you in advance!!

解决方案

When you call TThread.Synchronize the thread and method pointer are added to a global SyncList: TList in Classes.pas. In the main exe's TApplication.Idle routine calls CheckSynchronize, which checks the SyncList, but it's going to check the version in the exe instead of the one in the DLL. End result, your synchronized methods are never called.

The easiest fix would be to switch from DLLs to packages, which would eliminate the duplicate SyncList.

Another approach would be to override the exe's Application.OnIdle callback, and call your DLL's CheckSynchronize manually. You would need some help from the application for that though, since your DLL will have an Application object too, and that one won't work.

这篇关于Synchronize()挂断线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆