gpt4 book ai didi

播放 .wav 时的 C# 消息队列

转载 作者:行者123 更新时间:2023-11-30 22:42:29 24 4
gpt4 key购买 nike

我有一个程序可以在单击按钮时同步播放三个 .wav 文件。问题是,即使我在点击处理程序的第一条指令上禁用按钮,如果在播放声音时使用点击,其他鼠标点击事件也会排队,然后在播放完成时执行。我怎样才能避免这种情况?

这是我的点击处理程序,playSnippet_P1,2,3 以不同的顺序播放三个音频文件:

void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
this.Refresh();

//play a snippet for the current passage
switch (myProgram.condition)
{
case 1:
playSnippet_P1();
break;
case 2:
playSnippet_P2();
break;
case 3:
playSnippet_P3();
break;
default:
if (myProgram.debug)
{
MessageBox.Show("Error(frmPassage): Invalid condition set: " + myProgram.condition);
}
break;
}

//leave this phase once final passage is finished
if (snipsPlayed >= (myProgram.snipCount_1
+ myProgram.snipCount_2
+ myProgram.snipCount_3))
{
myProgram.phaseController.runNextPhase();
}

//reset the form to show text for next passage
if (snipsPlayed >= (getSnipCount(1) + getSnipCount(2)))
currentPassage = 2;
else if (snipsPlayed >= getSnipCount(1))
currentPassage = 1;
else
currentPassage = 0;

lblTitle.Text = "Passage " + randPOrder[currentPassage].ToString();

btnPlay.Enabled = true;
}

private void playSnippet_P1()
{
snipsPlayed++;

int cSnipCount = getCSnipCount();
int snipNum = (snipsPlayed % cSnipCount);
int subNum = getSubNum(snipsPlayed);
if (snipNum == 0)
snipNum = cSnipCount;

int rPassage = randPOrder[currentPassage];

//play "Next question is for..."
JE_SP.playSound(Application.StartupPath
+ "\\res\\audio\\next\\Next" + subNum.ToString()
+ ".wav", true);

//play snippet
JE_SP.playSound(Application.StartupPath
+ "\\res\\audio\\passages\\Snip" + rPassage.ToString()
+ "-" + snipNum.ToString()
+ ".wav", true);

//play question
JE_SP.playSound(Application.StartupPath
+ "\\res\\audio\\passages\\Q" + rPassage.ToString()
+ "-" + snipNum.ToString()
+ ".wav", true);

string[] writeMe =
{
rPassage.ToString(),
"\\res\\audio\\passages\\Snip" + rPassage.ToString()
+ "-" + snipNum.ToString(),
"\\res\\audio\\passages\\Q" + rPassage.ToString()
+ "-" + snipNum.ToString(),
subNum.ToString(),
myProgram.condition.ToString()
};

JE_Log.logData(writeMe, "\t", myProgram.groupFile);
}

最佳答案

此行为的更简单重现:

    private void button1_Click(object sender, EventArgs e) {
button1.Enabled = false;
System.Threading.Thread.Sleep(1000);
button1.Enabled = true;
}

问题是在 UI 线程繁忙时记录的鼠标点击进入消息队列并卡在那里,直到事件处理程序完成。当发生这种情况时,按钮已经再次启用,允许 Click 事件再次运行。

解决这个问题很麻烦,包括付出在工作线程上运行代码的代价。一个可能的好解决方法是在重新启用按钮之前清除消息队列并删除所有鼠标消息,但这在 Winforms 中并不容易。代码实际上在那里,但它是内部的。一个真正实用的修复方法可能会给我带来麻烦,但安全有效:

    private void button1_Click(object sender, EventArgs e) {
button1.Enabled = false;
System.Threading.Thread.Sleep(1000);
Application.DoEvents();
if (!button1.IsDisposed) button1.Enabled = true;
}

关于播放 .wav 时的 C# 消息队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4392712/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com