How to avoid a thread freezing when Main Application is Busy - delphi

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#.

Related

How to quantify number of waiting blocks on main thread?

I've inherited some code that throws any operation it can onto the main UI thread. For instance, when a network operation returns, the completion blocks are automatically run on the main thread and the programmers mix UI code with network requests willy-nilly.
How can I quantify the load or stress on the main UI thread, so that I can prove to a manager that putting everything on the main thread is a bad practice? I am hoping for a programmatic way to get this datum, because I also want to log it.

Does Electron's main thread block BrowserWindow?

I'm building an application that runs an Electron application. What I'm seeing is that when the main thread gets busy running its own operations, BrowserWindow's thread will get blocked (just like it does if the BrowserWindow itself is running javascript).
Are these sharing the same thread? If so, what is the best way to separate them?
First of all, it's not really Electron's main thread. It'd be more accurate to say that it's Node's thread.
Second, the Main process' main thread is used (among other things of course) to communicate between the Main process and the Renderer process that's used by the BrowserWindow, so if your main thread is performing a large synchronous operation, your main thread will block, and that could certainly affect the responsiveness of your window.
what is the best way to separate them?
I can't really provide a general solution that will be useful in all cases. You should present a specific example. What is your main thread busy doing?
You can look into using WebWorkers. See here.
In short, yes, Electron’s main thread can (somewhat counter-intuitively) “block” renderer UI.
Apparently[0], Electron relies on ongoing main-renderer communication a lot in background, and that is in addition to explicit IPC calls you make. Thus, if main thread is locking on some operations, UI will lag like crazy even if your own IPC calls are not blocked.
Ways around this:
You could use Node worker threads[1] in main.
You could use Web Workers, with or without spinning “hidden renderers”.
See also
[0] The Horror of Blocking Electron’s Main Process
[1] Gotchas on using Node worker threads in Electron: thread in #18540

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.

Understanding Multithreading in iOS

I am trying to understand multi-threading on iOS in more detail. I went through some of the class references like NSThread, NSRunLoop, NSTask..
First of all as indicated on the following link:
use of runloop
Runloop runs within a Thread.
So why do we need to define our own Runloop in our app? In the case of NSThread it is useful because some of time-consuming processes can run in a separate thread so that the app will still be responsive on the main thread.
Interacting with the thread's run loop may be useful if you have a thread whose work you want to continue periodically. That is, a run loop would do some work, and then when it is finished with that work, it would put the thread to rest for some time, then resume work at a later time -- effectively preventing the thread from exiting. You won't need to interact with them or configure/create them yourself regularly (only a small percentage of apps would qualify, if you are using high level abstractions such as Foundation because Foundation would set them up on your behalf in most scenarios).
If your secondary thread just does a specified task and does not need to wait for some external event (e.g. a download to finish), you would (typically) not need to interact with the run loop.
You might consider looking at using NSOperationQueues, NSOperations and NSBlockOperations instead as these will manage themselves, will allow for cancellation of tasks and can be scheduled on main and background threads.

Delphi Thread freeze

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.

Resources