Why using "SND_SYNC" in a "QueueUserWorkItem" bad?
Larry Osterman writes about a real error found in Microsoft's code, the offending code is
static DWORD WINAPI _PlayBeep(__in void* pv)
{
UNREFERENCED_PARAMETER(pv);
PlaySound(L".Default"NULL, SND_SYNC | SND_ALIAS);
return 0;
}
LRESULT WndProc(...)
{
:
:
case WM_KEYDOWN:
if (!_AcceptInputKeys(wParam, lParam))
{
QueueUserWorkItem(_PlayBeep, NULL, 0);
}
break;
}
and Larry asks:
Given the simplicity of the code ab开发者_开发知识库ove, to get the answer right, it’s not enough to say what’s wrong with the code (the problem should be blindingly obvious). You also need to be able to explain why this is so bad (in other words, what breaks when you do this).
The best answer is terse in the comments is not enough,
David's VERY close to what's going wrong - now think about the context of the application.
Can someone please explain fully what's happening when this code runs?
Read the answer page, it's got a very detailed explanation
http://blogs.msdn.com/b/larryosterman/archive/2009/06/29/what-s-wrong-with-this-code-part-26-the-answer.aspx
Basically, don't use QueueUserWorkItem
for long-running work items because this can cause thread exhaustion in your process, or even deadlock in a very hard to debug way if you wait for work items to complete on a (necessarily) finite-sized thread pool. Same goes for the .Net equivalent of this API ThreadPool.QueueUserWorkItem btw.
In this specific case, the workitem trigger ("press the down key") and the resulting thread workitem ("sound a sync beep") are very unbalanced, so that if user holds down or repeatedly hits his/her down key, the process will quickly hit fatal issues.
精彩评论