Socket select() blocks other UI threads - c++

In my MFC application , I am using TCP/IP socket for communcating and getting data from a server.During this process I am displaying a modelless dialog with static text and progress control.During communication I am updating the static text and progress control in a separate user thread(AfxBeginThread).
If I try to communicate to wrong ip the sockets select function with timeout value 5 secs blocking the displaying of dialog with static text and progress control(I.e the dialog hangs, the controls are getting displayed).
Once the socket comes out from select function the dialog is getting displayed properly.
How to fix this problem?

In MFC, I'd strongly recommend using CAsyncSockets, and just reacting when data comes in from the server. You probably have no need to spin up a thread at all.
If you were going to spin up a separate thread for part of the job, you'd want to allocate tasks to threads somewhat differently. You always want to leave UI updates in the main thread (the one that was created by default). If you were going to use (for example) a blocking socket, and call select on it, you'd want to move that work to a separate thread, and leave the UI updates in the thread that was created by default. Then the thread handling the socket could (for example) send messages to the UI thread to tell it about what's going on, so it could update the UI appropriately. But, as already noted, you probably just want to use a CAsyncSocket, in which case you won't need a second thread at all.

Related

Signal another thread within the same process

I have an application which processes certain data, and displays that in a UI.
Initially I had just a single thread, the main process, doing the work, i.e., retrieving the data for processing, processing the data, and then updating the UI. The data resides on another server.
However, the requirements for the application changed, and much more data has to be retrieved from the server and processed than previously thought. This is creating performance issues, since data has to retrieved, processed and then the UI has to figure out where it should be put
The UI is CListCtrl based MFC controls.
To combat this, I have split the processing n two threads, one which acquired the data and processes it, and another which will display it, i.e. the GUI.
I need some way to signal the UI thread, that the data has been fetched and processed. The thread is created using CreateThread. What is the best way to signal the other thread that it can do its own job?
I suggest the following: when your separate thread has to notify the GUI something you should call a PostMessage to the window containing the controls.
The message param should be a user defined message so something defined by you e.g.
#define WM_MYMESSAGE (WM_USER + 1)
The other two params (LPARAM and LPARAM) will contain data you need to pass to the GUI. So in CreateThread you need to pass some info about the window that will receive the message (the CWnd pointer if you use MFC, HWND handle otherwise).
Then you need to handle this message inside you window (see references about ON_COMMAND and the like macros)

How to make a thread in MFC for moving slider control with respect to audio file that is being played?

I was able to move SliderControl according to the position using CSliderCtrl::GetPos , being played by the program. (This is a part of my Music Player MFC project).
But I need to do this automatically without any notification/events ....
I thought of creating a thread that will move slider after clicking on play button.
You generally want to have exactly one thread updating the UI (and doing as little else as possible).
It would almost certainly work better to have a secondary thread playing the music. It can send a message to the UI thread, and the UI thread updates the slider control position when it receives that message.
It is always good to update the UI from the main thread instead of adding a new thread for updating UI. Better you can perform your background tasks by using a worker thread and update the UI by sending a message to the main thread when ever required.
In your case, you can have a worker thread to play the music and send a message to the main thread to update the slider position.
::SendMessage( AfxGetMainWnd()->m_hWnd, Message_Id, ( WPARAM )&String, 0 );
You can use the APIs CSliderCtrl::SetPos() to update the position.

SetScrollPos is blocking

In my multithreaded mfc app, m_view->SetScrollPos is blocking and all the app is freezed. The View is created in another thread, is this the reason for such behavior?
//SetScrollPos(SB_HORZ,pos);
::SetScrollPos(GetSafeHwnd(), SB_HORZ, pos, true);
The same happens with SetScrollInfo().
The reason is simple:
CHanging the scroll positions cause some window messages to be created. If you are in another thread and the thread hosting the window is not ready to process messages via the GetMessaage/PostMessage, the thread using SendMessage is blocked until the message can be delivered.
This is a normal and well documented behavior.
My advice: Never perform UI action from another thread. Choose a neutral communication method to inform the other thread about changes (PostMessage, Timer and data field, aso.)...

c++ mfc how to continue to use application while action is running [duplicate]

I am making an MFC (document/view) application and I want it to constantly listen in the background for when a device is connected and then automatically copy the files on the device without the user needing to interact or pause/disturb what they are doing.
Is creating a worker thread the same as having a background thread? Would I create it as a function in the document file or as a separate class?
Thanks,
Yes, they behave as a normal background threads, you have a function that gets parameter, and then you can enter your listener loop. I would put this function in separate class, maybe in a form of a singleton class, this way you can easily start/stop your device listener. If you would ever need to send information of progress from this worker thread to GUI, use PostMessage to you GUI windows.
as always MSDN provides tons of documentation:
http://msdn.microsoft.com/en-us/library/975t8ks0%28v=vs.80%29

How do I create Modal dialog in worker thread(Non-UI thread)?

I have written a sample MFC application in which there are two threads:
-Main thread ( UI thread)
-Worker thread ( non-UI thread)
I have a specific requirement to create a Modal dialog in Non-UI ( worker thread).
When I create the CDialog object and call DoModal on the same, it works. The dialog gets created and acts as Modal to the application. ( Win XP SP2 machine) But this does not work in Windows 2003 server machine.
The behavior in 2003 server is that, the Modal Dialog goes behind the application main Window and dialog will be brought to front only when I click on Main Window. It is not acting as Modal dialog to my application.
What could be the problem -- any ideas?
If creating UI controls in non-UI thread is the issue then is there any Win32 API which will allow me to link my worker thread to Main UI thread such that DoModal happens in Main thread. I tried AttachThreadInput but it is not working.
There is no reliable way to spread GUI modality across multiple threads. Every window is represented by an object referenced through a HWND which in turn has thread affinity. This is a left-over from the 16-bit days of Windows, where there was no multi threading. Consequently the HWNDs are not protected against concurrent access. The Old New Thing has an excellent series on "Thread affinity of user interface objects" (Part 1 2 3 Addendum).
Modality is implemented by first enabling the dialog window and then disabling its parent. The first step is safe while the second attempts to disable a window from a thread which is not the window's owning thread. Since en-/disabling windows modifies the object referenced through the HWND it represents a race condition.
The suggested solution is to confine your GUI to a single thread and communicate from your worker thread to the GUI thread to have it perform user interaction on the worker thread's behalf. The easiest way to accomplish this is to call SendMessage from the worker thread to block until the GUI thread's message handler returns. If the worker thread should continue to run while the dialog is displayed you could use PostMessage instead and communicate back to the worker thread using PostThreadMessage or signaling a synchronization object like an Event Object.
First of all, I'd like to agree with other posters that it's probably better to show the dialog on the main UI thread.
However, if you must, you can make a dialog on another thread modal with the following steps:
Pass your active window as an owner when creating the dialog.
When dialog is showing, iterate over your other windows and do them EnableWindow(FALSE). When the dialog is hiding, do the reverse. You will probably have to remember windows' enabled state and restore the original state, not just EnableWindow(TRUE).
Ensure that accelerators and other global commands will be ignored while the dialog is shown.
Note that (2) shouldn't be necessary provided that you do (1), but you've mentioned MFC, and I don't remember exactly how it behaves. It has it's own modal dialog implementation which may not exactly match Win32. If you're lucky, (1) and (3) will be enough.
While i don't know about the specifics of dialog handling on Server 2003, the simplest workaround to get on the main thread would be to use a custom window message, do ::SendMessage() and display the dialog in the message handler.
I recommend you not to do what the question subject suggests, and confine all UI to one thread. If you need the other thread to communicate with the user, create some messaging mechanism that will ask the UI thread to do it, and transport the results back.