在 C# 中安全回显 MIDI 数据
作为一个业余项目,我正在实现一个 MIDI 矩阵,以将多个 MIDI 键盘与声源互连。这里的关键要求是将输入端口上接收到的 MIDI 数据回显到选定的输出端口。
创建必要的 P/Invoke 声明和包装器,我注意到 MidiInProc
的 Win32 MIDI 文档指出:“应用程序不应从回调函数内部调用任何多媒体函数,因为这样做可能会导致死锁”。
鉴于从 MidiInProc
中调用 midiOutShortMsg
是不安全的,我当前的解决方案是将 MIDI 数据写入队列并设置一个事件。工作线程等待该事件并调用 midiOutShortMsg
。总体思路是这样的:-
static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
if( wMsg == MM_MIM_DATA )
{
data.EnQueue( dwParam1 ); //data is a Queue<uint>
dataReady.Set(); //dataReady is AutoResetEvent
}
}
void ThreadProc
{
while( !_done )
{
dataReady.WaitOne();
midiOutShortMsg( hMidiOut, data.DeQueue() );
}
}
然而,虽然这在测试中运行良好,但在调用 dataReady.Set()
和 InputCallBack
之间似乎存在一个机会之窗> 返回期间抢占可能允许工作线程调用 midiOutShortMsg
(尽管在另一个线程中)。
这种方法安全吗?
As a side project, I am implementing a MIDI matrix to interconnect a number of MIDI keyboards with sound sources. The key requirement here is to echo MIDI data received on an input port to a selected output port.
Having created the necessary P/Invoke declarations & wrappers, I notice that the Win32 MIDI documentation for MidiInProc
states: "Applications should not call any multimedia functions from inside the callback function, as doing so can cause a deadlock".
Given that it is unsafe to call midiOutShortMsg
from within a MidiInProc
, my current solution is to write MIDI data to a queue and set an event. A worker thread waits on the event and calls midiOutShortMsg
. The general idea is this:-
static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
if( wMsg == MM_MIM_DATA )
{
data.EnQueue( dwParam1 ); //data is a Queue<uint>
dataReady.Set(); //dataReady is AutoResetEvent
}
}
void ThreadProc
{
while( !_done )
{
dataReady.WaitOne();
midiOutShortMsg( hMidiOut, data.DeQueue() );
}
}
However, whilst this has been working fine in testing, there appears to be a window of opportunity between the call to dataReady.Set()
and InputCallBack
returning during which preemption could allow the worker thread to call midiOutShortMsg
(albeit in another thread).
Is this approach safe?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对我来说看起来很安全:即使您的两个线程同时运行,它仍然只有工作线程可能会阻塞,因此这不会导致您的输入回调死锁。
Looks safe to me: even if your two threads are running at the same time, it's still only the worker thread that might block, so this won't deadlock your input callback.
您的问题可能有点针对 StackOverflow 领域。如果这里没有人回答,请查看:http://groups.google .com/group/mididev?hl=en&lnk=
Your question might be a bit domain-specific for StackOverflow. If no one here answers it, check out: http://groups.google.com/group/mididev?hl=en&lnk=