I am working with CDialog in MFC.
In my dialog, I create a ui-thread:
CWinthread *threadCom = dynamic_cast<MyThreadClass*>(AfxBeginThread(RUNTIME_CLASS(MyThreadClass)));
Somewhere in my dialog class, I write:
threadCom->MyFunction();
My question is: "MyFuction()" is executed in main thread of dialog or ui-thread
Update after comment of AlexanderVX
For example, when user clicks on button on dialog
CMyDialog::OnBtnClicked() { threadCom->MyFunction(); }
"Calling a function" like calling a member function of a class is an action in your current thread.
If you want that Actions are executed asynchronously in the other thread you need some communication between the threads.
If the second thread has also a UI, it is possible to use messages (PostMessage) to inform the thread about an action. PostMessage is also a good way to inform the main thread about results from the worker thread.
If you need to transfer data too (more than a DWORD), you need a more complex data exchange that should be thread safe too.
Related
I want to have the code executed by the OnTimer event to be executed in a separate (non-Main) background thread. this code does not access or communicate with the main thread/GUI. Simple question, I get the timer (TJvThreadTimer) is executed in it's own background thread, but:
Does the code contained in TJvThreadTimer.OnTimer event get executed in that background thread as well?
It is unclear from the limited documentation.
Thanks......
If you look at the timer's source code for yourself, you will see that the OnTimer event handler is called inside of a class method that is Synchronize()'ed by the internal background thread, which means the event handler runs in the main UI thread.
I have a form that is responsible for creating and setting up an instance of an object, and then telling the object to go do its work. The process is a long one, so there's an area on the form where status messages appears to let the user know something is happening. Messages are set with a setMessage(string msg) function. To allow the form to remain responsive to events, I create a new thread for the object to run in, and pass it the setMessage function as a delegate to allow the object to set status messages on the form. This part is working properly. The main form is responsive and messages posted to its setMessage function appear as expected.
Because the process is a long one, and is made up of many steps, I want to allow the user to terminate the process before it's finished. To do this I created a volatile bool called _stopRequested and a function called shouldStop() that returns its value. This is also given to the object as a delegate. The object can tell if it should terminate by checking shouldStop() periodically, and if it's true, shut down gracefully.
Lastly, Windows controls are not thread safe, so the compiler will complain if a thread other than the one that created the control tries to manipulate it. Therefore, the setMessage function is wrapped in an if statement that tests for this and invokes the function using the parent thread if it's being called from the worker thread (see http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx for a description).
The problem arises when the user requests a shutdown. The main form sets _stopRequested to true and then waits for the child thread to finish before closing the application. It does this by executing _child.Join(). Now the parent thread (the one running the form) is in a Join state and can't do anything. The child thread (running the long process) detects the stop flag and attempts to shut down, but before it does, it posts a status message by calling it's setMessage delegate. That delegate points back to the main form, which figures out that the thread setting the message (child) is different than the thread that created the control (parent) and invokes the function in the parent thread. The parent thread is, of course, in a Join state and won't set the text on the text box until the child thread terminates. The child thread won't terminate because it's waiting for the delegate it called to return. Instant deadlock.
I've found examples of signaling a thread to terminate, and I've found examples of child threads sending messages to the parent thread, but I can't find any examples of both things happening at the same time. Can someone give me some pointers on how to avoid this deadlock? Specifically, I'd like the form to wait until the child thread terminates before closing the application but remain able to do work while it waits.
Thanks in advance for the advice.
1-(lazy) Dispatch the method from a new Thread so it doesn't lock
2-(re-think) The main UI thread should be able to control the child thread, so forget the _stopRequested and shouldStop() and implement a childThread.Abort() , abort does not kill the thread, but sends a ThreadAbortException
which can be handled or even canceled
catch(ThreadAbortException e)
{
ReleaseResources();
}
Make the ReleaseResources safe by making various checks such as:
resource != null
or
resource.IsClosed()
The ReleaseResources should be called normally without abort and also by abort.
3-(if possible)stop the child, via main thread call ReleaseResources()
You may have to implement a mix of these.
I have an application, where most of the actions take some time and I want to keep the GUI responsive at all times. The basic pattern of any action triggered by the user is as follows:
prepare the action (in the main thread)
execute the action (in a background thread while keeping the gui responsive)
display the results (in the main thread)
I tried several things to accomplish this but all of them are causing problems in the long run (seemingly random access violations in certain situations).
Prepare the action, then invoke a background thread and at the end of the background thread, use Synchronize to call an OnFinish event in the main thread.
Prepare the action, then invoke a background thread and at the end of the background thread, use PostMessage to inform the GUI thread that the results are ready.
Prepare the action, then invoke a background thread, then busy-wait (while calling Application.ProcessMessages) until the background thread is finished, then proceed with displaying the results.
I cannot come up with another alternative and none of this worked perfectly for me. What is the preferred way to do this?
1) Is the 'Orignal Delphi' way, forces the background thread to wait until the synchronized method has been executed and exposes the system to more deadlock-potential than I am happy with. TThread.Synchronize has been re-written at least twice. I used it once, on D3, and had problems. I looked at how it worked. I never used it again.
2) I the design I use most often. I use app-lifetime threads, (or thread pools), create inter-thread comms objects and queue them to background threads using a producer-consumer queue based on a TObjectQueue descendant. The background thread/s operate on the data/methods of the object, store results in the object and, when complete, PostMessage() the object, (cast to lParam) back to the main thread for GUI display of results in a message-handler, (cast the lParam back again). The background threads in the main GUI thread then never have to operate on the same object and never have to directly access any fields of each other.
I use a hidden window of the GUI thread, (created with RegisterWindowClass and CreateWindow), for the background threads to PostMessage to, comms object in LParam and 'target' TwinControl, (usually a TForm class), as WParam. The trivial wndproc for the hidden window just uses TwinControl.Perform() to pass on the LParam to a message-handler of the form. This is safer than PostMessaging the object directly to a TForm.handle - the handle can, unfortunately, change if the window is recreated. The hidden window never calls RecreateWindow() and so its handle never changes.
Producer-consumer queues 'out from GUI', inter-thread comms classes/objects and PostMessage() 'in to GUI' WILL work well - I've been doing it for decades.
Re-using the comms objects is fairly easy too - just create a load in a loop at startup, (preferably in an initialization section so that the comms objects outlive all forms), and push them onto a P-C queue - that's your pool. It's easier if the comms class has a private field for the pool instance - the 'releaseBackToPool' method then needs no parameters and, if there is more than one pool, ensures that the objects are always released back to their own pool.
3) Can't really improve on David Hefferman's comment. Just don't do it.
You can implement the pattern questioned by using OTL as demonstrated by the OTL author here
You could communicate data between threads as messages.
Thread1:
allocate memory for a data structure
fill it in
send a message to Thread2 with the pointer to this structure (you could either use Windows messages or implement a queue, insuring its enque and dequeue methods don't have race conditions)
possibly receive a response message from Thread2...
Thread2:
receive the message with the pointer to the data structure from Thread1
consume the data
deallocate the data structure's memory
possibly send a message back to Thread1 in a similar fashion (perhaps reusing the data structure, but then you don't deallocate it)
You may end up with more than 1 non-GUI thread if you want your GUI not only live, but also responding to some input, while the input that takes long time to be processed is being processed.
I use TIdHTTP component to load xml data from a bank in a seperate thread but my form is getting freezed during that time...
what could be the problem ?
I have a main form and thread class, in thread class i have a method called loadData and on thread::Execute i Synchronize(loadData);
when button gets clicked I created the instance of thread class like testThread *t=new testThread(false);
and that's all
when i click the button the main form freezes?
even seperate thread didn't help????
Please help!!!
Synchronize() is running your loadData() method in the context of the main thread, not in the context of your worker thread. That is why your main thread blocks while loadData() is busy. You are misusing Synchronize(), rendering your thread useless. You need to do the bulk of your thread work outside of Synchronize(), and then use Synchronize() only to perform small updates in the main thread when needed, like displaying status (even then, Synchronize() is not always the best choice for that).
At the moment, I am using WaitForSingleObject to wait for a sub-task thread to complete. Unfortunately, this causes my GUI to lock up. What I would like to do instead, is set a handler (in the GUI thread) that will be called after the sub-task thread is complete. Is there another function for this?
What you can do is to let the last thing that your thread does be posting a custom message to your window. Then handle that as a regular message using MFC's message map. If you cannot change the thread code, you can create a new thread that waits for your thread and then sends the message.
As you already noticed, it is not a good idea to lock up the GUI thread...
Edit: Posting the message is done using the PostMessage function as pointed out by Hans in the comments.
Could also have a look at MsgWaitForMultipleObjects (or MsgWaitForMultipleObjectsEx).
These allow a thread to wait for event handles and service windows messages (examine the return value to see what causes the call to return). Examples of usage should be available via a goodle search.
http://msdn.microsoft.com/en-us/library/ms684245(VS.85).aspx