Problem with PPL in MSVC 2010 using MFC

I have encountered with a problem with Parallel Pattern Library when using it along with MFC. I have a method class, wich responds to a button click:

void Ctest_taskDlg::OnBnClickedButton1()
{

using namespace Concurrency;
tasks.run([&]{add_to_in();});
tasks.run([&]{add_to_out();});
tasks.wait();
::AfxMessageBox(_T("Done"));
}


add_to_in() and add_to_out() is a member fucntions of Ctest_taskDlg class, each of them prints a 10 000 symbols to a RichEdit control. A task_group tasks is a member of Ctest_taskDlg class too.

When I press the button, it executes only add_to_out() function, and then main window of an application is freezes.

What would cause this? Thanks in advance!
Last edited on
You cannot access a user interface element from a thread that did not create the said user interface element. In other words: You are probably trying to access the RichEdit control directly from the member functions, but you are running in a different thread, which is bad.

Post the code of add_to_in() (and add_to_out() if it isn't too much trouble).
What is much confusing that if I delete tasks.wait(); line, add_to_in() and add_to_out functions work properly.

Here is the code of procedures:

1
2
3
4
5
6
7
8
9
10
11
void Ctest_taskDlg::add_to_in()
{
		int counter = 0;
		do
		{
			int ln = seq_in_control.GetWindowTextLength();
			seq_in_control.SetSel(ln, ln);
			seq_in_control.ReplaceSel(_T("A"));
			counter++;
		} while(counter < 2000);
}




1
2
3
4
5
6
7
8
9
10
11
void Ctest_taskDlg::add_to_out()
{
		int counter = 0;
		do
		{
			int ln = seq_out_control.GetWindowTextLength();
			seq_out_control.SetSel(ln, ln);
			seq_out_control.ReplaceSel(_T("B"));
			counter++;
		} while(counter < 2000);
}
It is not confusing if you know how Windows works and how message pumps work.

Basically you are breaking a major rule (one rule that I broke myself not so long ago and cost me a support incident with Microsoft). The rule is: NEVER freeze a UI thread indefinitely because you never know when it is required to pump a message. The call to tasks.wait() freezes the UI thread indefinitely, and most likely SetSel() and ReplaceSel() use SendMessage() (or an equivalent function) to communicate the needful to the RichEdit control.

The action of sending the message to the control tells windows to switch thread contexts if it must and execute the the UI thread in order to pump the sent message while this worker thread is frozen waiting for the message to be processed. But your call to tasks.wait() also has the UI thread frozen, meaning you end up with a deadlock: UI thread is waiting for worker thread to finish while worker thread is waiting for UI thread to process the message.

What Microsoft recommended me: Change the simple infinite wait to a wait that can pump messages. In pure Win32 programming, that meant changing WaitForSingleObject() to MsgWaitForMultipleObjects(). In PPL, I don't know the equivalent. Look it up.
webJose, thank you very much, very helpful.
Topic archived. No new replies allowed.