XAudio2 示例代码使用“异步”而不是“阻塞”I/O 的原因是最佳实践。它在“工作线程”中完成的原因主要是为了简单,因为在游戏中音频通常由它自己的线程处理以避免故障并保持渲染/更新循环不同。
您可以将异步/提交作为Update
循环的一部分来处理,但前提是您确定它总是能够足够快地得到处理以避免出现故障。这实际上是我在GitHub 上使用最新的旧版 DirectX SDK 版本的 XAudio2 流式传输示例所采用的方法
可以使用更好的实现ReadFileEx
,但工作线程方法更简单。此外,由于在 Windows 8 中如何实现 API 分区的一些怪癖,ReadFileEx
在 Windows Store 平台/Windows phone 8/UWP 上不受支持,因此教程/示例避免使用它来避免指向不适用的方向适用于所有 Microsoft 平台。FWIW,ReadFileEx
并WriteFileEx
在 Windows 10 周年更新 (14393) 中重新添加到 UWP。
ERROR_IO_PENDING
请注意,在如何处理场景时,在等待重叠 I/O 的事件中有一些怪癖。此功能在 Windows 8 或更高版本中得到改进和简化GetOverlappedResultEx
。对于DirectX Tool Kit for Audio中的波形库阅读器,我使用此模式为旧平台和新平台构建:
bool wait = false;
if( !ReadFile( hFile.get(), &m_data, sizeof( m_data ), nullptr, &request ) )
{
DWORD error = GetLastError();
if ( error != ERROR_IO_PENDING )
return HRESULT_FROM_WIN32( error );
wait = true;
}
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
result = GetOverlappedResultEx( hFile.get(), &request, &bytes, INFINITE, FALSE );
#else
if ( wait )
(void)WaitForSingleObject( m_event.get(), INFINITE );
result = GetOverlappedResult( hFile.get(), &request, &bytes, FALSE );
#endif
if ( !result || ( bytes != sizeof( m_data ) ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}