MFC/3rd party multithreading hang - multithreading

I'm currently working on a program using MFC. The current third party function starts a thread after an action has been completed using MFC (ie. Checking a checkbox, which starts a MFC thread I believe).
The problem occurs when I check the checkbox, at which point the entire program hangs. I read a few interesting discussions on CProgramming and msdn, it seems that the problem occurs because the new third party thread is calling WaitToSomething() when MFC is updating a control.
Something interesting to note:
When I debug the program, the program hangs (aka. repeatedly calls WaitToRead() ) after I check the checkbox and a new thread is trying to start
When I run the program without debugger, the program is fine UNTIL I switch to another window (ie. Internet browser, Notepad, etc)
My hypothesis:
check to make sure that MFC has finished updating the control before starting a new thread
If anyone has any suggestions or solutions, please leave a comment. Thanks.
Edit:
MFC is not thread-safe at object level (only at class level), so problem occurs when two threads work on the same CButton object.
Q: How do I make it thread safe?

A colleague helped me figure out what the problem was.
The reason why it was hanging is because that the control containing the checkbox is a child dialog, and when it finished updating the message never got passed up to its parent (so when 3rd party thread calls WaitFor(), the MFC thread never completes because a parent dialog thinks its child is still updating the controls).
Fix:
Under 'Properties' in the child dialog's control, set the 'Control' flag to true (and if it has children, set the 'Control Parent' flag to true as well).
Hope this helps.

Related

Is it possible to Derive class from CWinThread Class in dialog based application

I am working with Dialog based application.
My Question is that, I want to show Waiting dialog, until some database operation carried out.
i Used Derived class from CWinThread, but problem is that, when this thread close, the background (Main application dialog) remains at deactivated means( it hide behind another window).
i am thinking that, this is happening because of WaitDialog used CWinThread class.
The problem is not unique to a dialog based application. Creating windows of any kind in more than one thread is difficult and not recommended. In your case it sounds like your wait dialog is modal, while its parent dialog is in another thread. That is even worse and can lead to deadlocks between threads.
The reliable solution is to put the wait dialog (and all other GUI) in the main thread, and the lengthy database processing in a secondary thread.
Another alternative would be to use a Modeless Dialogbox which can also optionally show the status and call the DestroyWindow function when the database operation is completed -- you may need to disable some operations of the main window while the Modeless Dialogbox is visible, though.
From the comments on my previous answer, it looks like that alternative is not viable in this situation.
Maybe a better way would be to create a normal modal "wait" dialog box, start the background thread in the dialog's InitDialog, periodically check the status of the thread using a timer and end the dialog when the thread completes?

Visual C Multi-Threading (Please Help)?

I have written a .NET program, using Windows form Application.
My application is fairly simple.
Basically, I have two simple buttons on my form.
When the form is first loaded, I set up a global variable (bool run = true).
And my first button is essentially a very simple while loop.
while(run)
{
// do some code
}
And what I want to do, is have the second button set the value of the boolean to false (bool run = false).
But, once I clicked the first button, I cannot even touch the second button!
I have read quite about this, and I think my solution is to use a multi-threading.
I have found some example codes on line for multi-threading, and I tried to incorporate those, but I don't know why I cannot get it to work. Once I click button #1, there is no way for me to be able to click button #2.
Your UI thread should not have any infinite or a wait-on-something - never! You must not block the UI for anything (other than simple calculations, validations, user confirmation etc). You should make a thread for performing length task, and let that thread communicate to UI thread using asynchronous (or synchronous, if you prefer) communication.
On native Windows GUI application, you can use PostMessage (async), or SendMessage (sync). For .NET GUI applications, you can use Control.BeginInvoke (async), or Control.Invoke (sync).
Please read this article on how this is done.

Problem with MFC CWnd::CreateControl method

I have a problem with CWnd::CreateControl method while loading custom ActiveX control from the MFC application.
I have list of Custom ActiveX controls which are implemented Create method inturn calling CWnd::CreateControl method.
I am having Dialog window, in the OnInitDialog, I have started timer thread using Settimer(). In the OnTimer event, I am loading all the controls by calling respective control's Create method. After opening and closing the dialog window more than 10 times, OnTimer is not able to load the contols.
I checked the return value which is false and the GetLastError which is 0x0 (Operation successful). I was debugging completely and checked all the possiblities of errors before this event. I couldn't find the root cause what made not loading the controls.
You may want to refer the below question similar occurence of the problem
Exception while opening file
The similarity being it was working fine but after sometime it would throw exception and when we check the error message it would be no error occured. The issue wont be directly at the line that causes exception. It would be lurking elsewhere in the application.
In my case when i changed the way i was accessing the method and it started working.

How to avoid use of timer when using TThread to communicate with UI thread

I have a TThread which receives and sends to a device on a COM port. After I read the data, I want to activate the GUI (not in the same thread) using Synchronize(function name). However, when I call the GUI's form function to perform a button click, I get an access violation. I checked to see if the form's value is null and it is not, since this would be an obvious reason for access violation. Right now, I am setting global flags and using a timer that continuously checks to see if a certain condition is met and if so, then I fire off the button click event in that form. That seems to be the only way to avoid getting the access violation.
I really don't like timers so is there a way to avoid having to use a timer on the form?
You can post a message to the window in question. The timer works in a similar manner. It just fires off a windows message inside the form. You obviously have a handle to the window.
CWnd::PostMessage(...) Don't use send message, it gets processed inline and could cause your thread to stop working.
Typically when you have a worker thread that attempts to access Guithread, they conflict. It's been a while since I've used MFC and threading but that's what I remember. I believe it's documented to work that way.
I found the problem. I thought I was checking if my Form was null, but I was not. I fixed it making sure the form I was referencing is not null.
Edit: Turns out that one of the forms that is called when I call Fbutton1Click() is Modal so it blocks my thread. I ended having to go back to a timer to call the button click instead.. oh well.

What is the Best Practice for converting a vb6 standard exe to a activex exe?

i have a legacy massive vb6 editor with plenty of 3rd party libraries and controls and recently there is a need to set it up to make it multi thread so i can run a few other forms independently from the main editor form. Basically there's minimum communication between these other forms and the main editor except for running the other forms on a click of a button from the main page.
So from a lot of googling i found a method which converts the current app into a multi threading one by setting it up as an activex exe and adding a class set to global-multi-use to allow this to happen. Now while doing editing and testing via debugging mode, i found that when i exit a lot of weird crash will happen sometimes.
'main.frm - button click call
'On the button click, create a new object
Set obj = CreateObject("MyApp.clsThread")
Call obj.NewThread
'clsThread
' Create a new form and load it to run on a new thread
Public Sub NewThread()
Dim frm As Object
Set frm = New frmDogbert
Load frmDogbert
frm.show
Set frm = Nothing
End Sub
So what do i absolutely must know when i do this,i.e. potential problems,etc?, as i'm fearing that the app seems to be getting more unstable. Or is there a better way to do this?
Updates:
Instead of forcefully hacking my app into a pseudo multithreading app, i've taken the advice from the good people here and refactor out the component into standard exe and reverted back my app to a standard exe and call them via shell. Works beautifully :)
Thanks
Visual Basic 6 is not multi threading in of itself. The difference in the multi-tasking behavior between a ActiveX EXE and a ActiveX DLL is only apparent when referenced from another VB6 EXE. Objects instantiated from a Global Multi-Use Class defined in a ActiveX EXE run in their own context. Object instantiated from a ActiveX DLL are run in the context of the calling EXE.
Now multi-threading can be hacked into VB6 but it is very touchy and has a lot of don't (for example you can't use the stop button in the IDE to stop a debugging session or the program will crash).
What a ActiveX EXE is good is for spawning a separate but related instance that can run separately without halting the main program. Based on your brief description I would say your best best is to keep your EXE as is but more the forms/modules/classes to a separate EXE and have the original EXE reference the ActiveX EXE.
Note that you don't have to compile down to .EXE you can change the extension to .DLL and it is still a activeX EXE. You do this so that the user doesn't mistakely run the ActiveX EXE by itself.
Can you clarify the question a bit? I don't understand why it needs to be multi-threaded? Why can't you just display the forms non-modal, then they will all be visible and responsive at the same time. Unless you have some background processing operating all the time in your main form, which sounds unlikely from your question as it would lock up the main form as well as the others.
Melaos says: Well the main editor frm is the main thing here and I need to allow the user to run additional forms to do some other stuff like uploading things to our server and convert video files to other formats. And these forms use shell to call other exes. And the running time takes quite a while.
In that case I recommend making the other forms into separate EXEs rather than use multithreading, which is difficult. You say there's little communication from the main form to the subforms - it just shows them. Therefore you don't even need to make the subforms ActiveX EXEs. Just make them standard EXEs and shell them from the main form.

Resources