为啥在“QueueUserWorkItem”中使用“SND_SYNC”不好?

Posted

技术标签:

【中文标题】为啥在“QueueUserWorkItem”中使用“SND_SYNC”不好?【英文标题】:Why using "SND_SYNC" in a "QueueUserWorkItem" bad?为什么在“QueueUserWorkItem”中使用“SND_SYNC”不好? 【发布时间】:2011-06-22 16:22:44 【问题描述】:

Larry Osterman writes 关于在微软的代码中发现一个真正的错误,有问题的代码是

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;

拉里问:

鉴于代码的简单性 上面,为了得到正确的答案,它是 不足以说明有什么问题 代码(问题应该是 很明显)。你还需要 能够解释为什么这很糟糕 (换句话说,当你 这样做)。

最好的答案是在 cmets 中简洁是不够的,

大卫非常接近即将发生的事情 错了——现在想想 应用程序。

有人可以解释一下这段代码运行时发生了什么吗?

【问题讨论】:

【参考方案1】:

阅读回答页,里面有很详细的解释

http://blogs.msdn.com/b/larryosterman/archive/2009/06/29/what-s-wrong-with-this-code-part-26-the-answer.aspx

基本上,不要将QueueUserWorkItem 用于长时间运行的工作项,因为这可能会导致您的进程中的线程耗尽,或者如果您等待工作项在一个(必须) 有限大小的线程池。此 API ThreadPool.QueueUserWorkItem btw 的 .Net 等效项也是如此。

在这种特定情况下,工作项触发器(“按下向下键”)和生成的线程工作项(“发出同步哔声”)非常不平衡,因此如果用户按住或反复按下他/她的向下键,该过程将很快遇到致命问题。

【讨论】:

以上是关于为啥在“QueueUserWorkItem”中使用“SND_SYNC”不好?的主要内容,如果未能解决你的问题,请参考以下文章

为啥通过调用Task.Run和ThreadPool.QueueUserWorkItem排队到ThreadPool时线程数增加了不止一个?

在高流量场景中使用 ASP.NET 中的 ThreadPool.QueueUserWorkItem

如何中止使用 ThreadPool.QueueUserWorkItem 创建的线程

使用私有成员函数调用 Win32 QueueUserWorkItem()

使用 QueueUserWorkItem(不是 .NET)等待工作项完成池化

ThreadPool.QueueUserWorkItem 方法 (WaitCallback)