我正在尝试更新文本框以显示 3-2-1,然后播放声音。这有点有效,但我的声音立即开始播放,因为线程没有阻塞主线程。我尝试添加另一个 Thread.Sleep(4000);在他的主线程中,但是一切都只是等待并且文本框不显示运行数字。我在文本框中输入数字 1 并且播放声音:(
那么如何暂停主线程,同时 TextBox 运行 3-2-1 然后发出声音?
´´´ private void Button_Click(对象发送者, RoutedEventArgs e) {
try
{
ThreadPool.QueueUserWorkItem(async (o) =>
{ Dispatcher.Invoke((Action)(() => outputTextBox.Text = "3"));
await Task.Delay(1000);
Dispatcher.Invoke((Action)(() => outputTextBox.Text = "2"));
await Task.Delay(1000);
Dispatcher.Invoke((Action)(() => outputTextBox.Text = "1"));
await Task.Delay(3000);
});
任务.延迟(3000);
if (waveOut!=null ) waveOut.Stop();
Songs = db.Songs;
int r = rnd.Next(Songs.Count);
System.Diagnostics.Debug.WriteLine(r);
String name = ((Song)Songs[r]).Name1;
System.Diagnostics.Debug.WriteLine(name);
int start = ((Song)Songs[r]).Start1;
System.Diagnostics.Debug.WriteLine(start);
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
var ms = File.OpenRead("C:\\"+name);
var rdr = new Mp3FileReader(ms);
var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr);
wavStream.Skip(start);
var baStream = new BlockAlignReductionStream(wavStream);
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
waveOut.Init(baStream);
waveOut.Play();
/*
while (waveOut.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
*/
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
´´´
使用
async
关键字标记您的事件处理程序,并在播放声音之前等待 Delay
调用:
private async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
outputTextBox.Text = "3";
await Task.Delay(1000);
outputTextBox.Text = "2";
await Task.Delay(1000);
outputTextBox.Text = "1";
await Task.Delay(1000);
// play sound:
if (waveOut!=null)
waveOut.Stop();
Songs = db.Songs;
int r = rnd.Next(Songs.Count);
System.Diagnostics.Debug.WriteLine(r);
String name = ((Song)Songs[r]).Name1;
System.Diagnostics.Debug.WriteLine(name);
int start = ((Song)Songs[r]).Start1;
System.Diagnostics.Debug.WriteLine(start);
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
var ms = File.OpenRead("C:\\"+name);
var rdr = new Mp3FileReader(ms);
var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr);
wavStream.Skip(start);
var baStream = new BlockAlignReductionStream(wavStream);
waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
waveOut.Init(baStream);
waveOut.Play();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
这里没有理由涉及线程池。
正如评论中提到的,只需使用async 和await。我强烈建议您阅读有关它的文档,因为您似乎对其使用感到困惑。
private async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
// The await call will make it wait until the task is completed
// (including the delay of 3 seconds) then it will resume the execution
// of the code after the `await`.
outputTextBox.Text = "3";
await Task.Delay(1000);
outputTextBox.Text = "2";
await Task.Delay(1000);
outputTextBox.Text = "1";
await Task.Delay(1000);
this.PlaySong();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
async
await
的有趣之处在于它不会暂停主线程,因此您的应用程序不会显得无响应。