Delphi Thread freeze - delphi

I coding a service application that have two threads.
First thread, show a form with label.
Second thread, query ADO.
First thread always freezing with Hourglass cursor and no label caption.
Please help.

If you're trying to show a form from within a thread that is not the main thread, then you will run into strange things like this. The most notable of which is that if the form and label are created in the non-main thread, then you don't have a message loop to process the messages. If the form was created in the main thread, but you're attempting to show it from the non-main thread, then it is likely a dead lock due to how Windows deals with messages and threads.
When a window handle is created it is tied to the thread on which it was created. This means that Windows will ensure that any messages sent to that handle are processed on that thread.
I would strongly suggest you read up on how window messages, message queues, and handles all interact and function in a multi-threaded environment. If not done correctly, you are assured of some very odd and possibly unpredictable behavior.

I would call your condition either a Race, a Deadlock, or some other kind of error like that. As Allen says, if the background thread makes ANY direct access to the VCL controls, without using TThread.Synchronize(myMethod) to invoke the myMethod that touches your VCL foreground, then this alone would cause your trouble.
Post more information, including a sample of your code please.

Related

C++Builder - Correct way to take action on application startup

Using C++Builder XE5.
My main form has an Indy blocking socket which I would like to connect to and block on, as soon as the application has started up and the main form shown.
What is the correct way to do this?
In previous versions or C++Builder, OnCreate and AfterConstruction were both unreliable. Normally I put code like this in the main .cpp file, just before Application->Run(), however that is not appropriate here because I am going to block (and rely on the TIdAntifreeze for message processing).
One way I thought of is to define a custom windows message and post that to myself, but I'm wondering if there is a "proper" way.
My main form has an Indy blocking socket which I would like to connect to and block on, as soon as the application has started up and the main form shown.
Do you really need to do blocking I/O in the main UI thread? Blocking operations, such as Indy's socket I/O, should be done in a worker thread instead.
If the main thread needs to block on a socket operation while still processing UI messages, you can use a waitable event object via CreateEvent() with MsgWaitForMultipleObject() in a loop that calls Application->ProcessMessages() only when there are messages to process, breaking the loop when the event is signaled. This is not generally the best option though. An event-driven model, where the worker thread notifies the main thread of activity/results, would be a better choice. You really should never block the main UI thread for anything.
What is the correct way to do this?
I would suggest having the MainForm constructor create a worker thread, and then the thread can manage the socket operations and synchronize with the main UI when needed.
In previous versions or C++Builder, OnCreate and AfterConstruction were both unreliable.
AfterConstruction() is reliable, and always has been. It is only the OnCreate event that was unreliable, and should never be used in C++ in favor of the constructor instead.
Normally I put code like this in the main .cpp file, just before Application->Run(), however that is not appropriate here because I am going to block (and rely on the TIdAntifreeze for message processing).
You really should not rely on TIdAntiFreeze, a worker thread is a better choice.
One way I thought of is to define a custom windows message and post that to myself
That will work. I use that technique myself at times. Just be aware that it is an HWND-based solution, so you need to make sure the HWND you post to is not destroyed/recreated after you post the message and before it is retrieved from the message queue. If you use the MainForm's HWND, post the message in the OnShow event. A better option is to use AllocateHWnd() to create a dedicated HWND for your custom messages.

Run a form in a separate thread

Let's say I have a form Foo.
How do I create an instance of that which runs in it's own thread and gets updated even though the main application thread might be busy doing something else? For instance handling blocking network communication or something like that.
I understand the fundamentals and that I need to create a new thread, create the form instance in that thread etc. But then I figure I need an update loop for that thread/window and I'm not at all sure how that should look.
You shouldn't create forms in threads any than your main application thread, because windows message queue is associated only with this main thread.
Think differently: To be sure, that your forms are always updated and responsive, create separate threads for busy work like handling blocking newtork communications and so on, not for forms. In such case, after creating new thread, main form continues to pump messages from it's queue, while function in different thread is doing dirty-work that you need. When the working thread finishes, it can inform main thread about results, using PostMessage() WinAPI function. You should just simply provide handlers for such custom messages in your forms, and they will communicate with working threads seamlessly.
Also, if your "busy work" isn't very complicated, you can even deal without additional threads, by running your work in the form thread, and just calling ProcessMessages() function from time to time, to keep the form updated.

Keep one form updating even if another is working

I created a small form that I want to put on top of other forms when they are working. Basically like a small "Loading... Please wait" notification. It includes an animated TGIFImage. The problem is that when another form is working hard the animation and updating of this form stutters. Probably since they are running in the same thread? Is there a quick and easy way to have this little form always update nicely? Perhaps a quick way to make sure it's handled in it´s own thread?
Move the hard work into an actual thread of its own. See the TThread class. Display your Form normally, then start the thread, then close the Form when the thread is done with its work. Have the thread post status updates to the main thread asynchronously if needed (such as for progress bars, etc) so the worker thread is not slowed down waiting for the main thread.
Thanx for the answer Remy Lebeau. I wanted to have to change as little as possible to the existing code though and not move existing code into threads etc. So what I ended up doing was to have a little factory for my notifications that spawns a thread and create the form in that thread. That way I basically only need to wrap my existing code with a Show and a Hide call.

Delphi - Message loop for Form created in DirectShow filter goes dead

I have a DirectShow filter created with Delphi Pro 6 and the DSPACK direct show library. I'm running under windows XP. I've tried creating the form dynamically when the container class for the DirectFilter has its constructor called, passing NIL into the constructor as the AOwner parameter (TMyForm.Create(nil) and then calling the Form's Show() method. The form does show but then appears to stop receiving windows messages because it never repaints and does not respond to input. As a test I then tried creating my own WndProc() and overriding the Form's WndProc(). My WndProc() did get called once but never again.
I'm guessing it's because I'm a DLL and the context that I am running in is not "friendly" to the window message handler for the form; perhaps something to do with the thread that calls it or whatever. If someone could give me a tip on how to solve this or what the proper way to create a persistent window is from the context of a DirectShow filter I'd appreciate it. Note, as I said the window needs to be persistent so I can't create it as a Filter property page.
Thanks,
Robert
I can't help you with the DirectShow filter specifics, but I feel that some general information about windows and message handling might help.
Windows have thread affinity, which means that all messages for a window will be handled in the context of the thread that created it. That means that this thread needs to have the standard message processing loop, the low level equivalent of Application.ProcessMessages(). Both messages from the same and from other threads will be queued in the message queue of the creating thread, and the message loop will get them, (optionally) translate them, and dispatch them to the window handler of the target window.
What you are describing could be caused by either
not having a message processing queue in the thread that creates the window, or
creating the window in the wrong thread
(Note that these are essentially the same, but stated like this it becomes apparent that there may be different problems that cause this, which need to be fixed in different ways - either the window needs to be created in a different thread, or a processing loop needs to be created in the thread.)
You need to find out which of the two causes your window not to process messages. You don't necessarily need to override WndProc(), message handling methods for distinct messages will work (or not work) the same. That your WndProc() was called once doesn't really tell you much, because under some circumstances messages sent from the same thread will be handled without the message loop, by calling the window proc directly.
Since your filter resides in a DLL I don't think that creating your own message loop would be the right thing. This works for a modal dialog, which will be created, the message loop will run until the dialog is closed, and then the message loop will terminate and the DLL function will return. It will not work for a DLL exported function that will be called and needs to return all while the message loop is still running. I assume the framework that creates and calls those filters will handle the message loop as well. However, that is a gut feeling, not knowing about DirectShow filters this may well be wrong.
What might help you to debug this is a tool like Spy++ from Visual Studio, with which you can show information about windows, log messages sent to them or to all windows in the same process or thread, show window hierarchies and do a lot of other interesting things. If you don't have that, there are a lot of clones (some freeware) on the net, which Google should turn up. Trying to show the messages sent to all windows of the same thread or process should tell you whether a message loop is running. You should also be able to get more information by running SysInternals Process Explorer or similar tools.

How to avoid a thread freezing when Main Application is Busy

I'm having a bit of a problem. I want to display a progress form that just shows an animation on a when the main application preforms heavy operations.
I've done this in a thread and it works fine when the user isn't preforming any operations. But it just stops when my main application is busy.
I'm not able to put Application.ProcessMessages in between the different lines of code because I'm using 3rdparty components with heavy processing time.
My idea was to create a new process and in the process create a thread that execures the animation. Now that wouldn't stop the thread form executing when the main application performs heavy operations.
But as I see it you can only create a new process if you executes a new program.
Does any one have a solution on how to make a thread continue executing even when the main application is busy?
/Brian
If your worker thread does not have a lower priority than the main thread, you don't use the Synchronize() method, don't call SendMessage() and don't try to acquire any synchronization object that the main GUI thread has already acquired, then your secondary thread should continue to work.
As the VCL isn't thread-safe people do often advise to use Synchronize() to execute code to update VCL controls synchronously in the context of the VCL thread. This however does not work if the VCL thread is itself busy. Your worker thread will block until the main thread continues to process messages.
Your application design is unfortunate, anyway. You should perform all lengthy operations in worker threads, and keep the main thread responsive for user interaction. Even with the fancy animation your app will appear hung to the user since it won't redraw while the VCL thread is busy doing other things and processes no messages. Try to put your lengthy code in worker threads and perform your animation in timer events in the main thread.
Your logic is backward. Your thread should be doing the "heavy work", and passing messages to your main application to update the progress or animation.
If you leave all the "heavy work" in your main application, the other thread won't get enough chances to execute, which means it won't get a chance to update anything. Besides, all access to the GUI (VCL controls) must happen in the application's main thread; the VCL isn't thread-safe. (Neither is Windows itself, when it comes to visual controls.)
If by "Does any one have a solution on how to make a thread continue executing even when the main application is busy?" you mean that main thread is busy you should move the code that is consumming main thread to another other thread. In other words main thread should be responsible for starting and stopping actions and not executing them.
Disclaymer:
Actually I don't know delphy but I think/hope the concepts are quite similar to C++ or C#.

Resources