Click to See Complete Forum and Search --> : CDialog and Multithreading


neoneuf
December 7th, 2011, 02:39 AM
I have 2 threads that need to access to a modeless dialog.
The modeless dialog is created with new operator.
I use criticalsections to synchronise access to the Cdialog between the 2 threads.

Inside the cdialog, I have a clistbox.
One of the thread call findstringexact on the listbox.

The problem is that someimes the call to findstringexact doesn't return at all, which of course blocks the other thread which is waiting to access to the cdialog.

What's the problem ? is it due to creating the dialog dynamically with new ?

VictorN
December 7th, 2011, 03:38 AM
I have 2 threads that need to access to a modeless dialog.
The modeless dialog is created with new operator.
...
The problem is that someimes the call to findstringexact doesn't return at all, which of course blocks the other thread which is waiting to access to the cdialog.

What's the problem ? is it due to creating the dialog dynamically with new ?No, it doesn't matter whether you create the dialog on the stack or in the heap.

But you should never directly access (using SendMessage) any window/control belonging to another thread!

neoneuf
December 7th, 2011, 09:54 AM
Thank you.
Using sendmessage seems to have resolved the problem.

VictorN
December 7th, 2011, 10:03 AM
Thank you.
Using sendmessage seems to have resolved the problem.
No! Using SendMessage between the thread may cause a deadlock!
You should use PostMessage instead.

MikeAThon
December 12th, 2011, 06:17 PM
PostMessage won't help in this instance, since PostMessage will ignore the return value, and the return value is the thing that's needed (it's the index of the string being searched for).

The basic problem is this: worker threads should never touch the UI: only the main GUI thread should ever touch the UI. In this particular case, the function FindStringExact is a shallow wrapper over a SendMessage to the list with LB_FINDSTRINGEXACT. This means that a worker thread should never call FindStringExact, and should never SendMessage LB_FINDSTRINGEXACT. Both could result in deadlock, for reasons that are complex but can be found with reasonable searching and study.

Part of the problem arises because there is no separation between the data and the control that displays the data. The list box will both store the data and display it.

One solution is to keep an independent list of the strings being displayed by the list box, and to search through the list (synchronized using a CRITICAL_SECTION or other synchronization object). This separates the data (which is now stored in an independent list) from the control that displays it.

But as VictorN advises, never use SendMessage (or a wrapper over SendMessage) from a worker thread to the main GUI thread, since that is almost always a recipe for deadlock.

Mike