WPF中更新TextBox显示3-2-1后播放声音,如何暂停主线程?
解决WPF中TextBox依次显示3-2-1后再播放音频的问题
问题根源
- 原代码里线程池任务和主线程的播放逻辑是并行执行的,导致音频直接提前播放
- 使用
Thread.Sleep会阻塞UI线程,界面无法实时更新TextBox的内容 Task.Delay(3000)没有加await,根本起不到等待作用
解决方案
把按钮点击事件方法标记为async void,利用异步await特性实现等待逻辑,既不会阻塞UI线程,又能保证数字显示完成后再执行音频播放。
修改后的代码
private async void Button_Click(object sender, RoutedEventArgs e) { try { // 依次显示3-2-1,每次等待1秒 outputTextBox.Text = "3"; await Task.Delay(1000); outputTextBox.Text = "2"; await Task.Delay(1000); outputTextBox.Text = "1"; await Task.Delay(3000); // 保持原逻辑中显示1后的3秒等待 // 音频播放逻辑,现在会在数字显示完成后执行 if (waveOut != null) { waveOut.Stop(); waveOut.Dispose(); // 释放旧资源,避免内存泄漏 waveOut = null; } 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); 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关键字,返回void(WPF事件处理方法允许使用async void) - 移除了线程池调度和
Dispatcher.Invoke,因为await Task.Delay后会自动回到UI线程上下文,直接更新TextBox即可 - 所有等待操作都用
await Task.Delay(),既实现等待又不阻塞UI,保证数字能依次显示 - 音频播放逻辑放在所有数字显示和等待完成之后,严格保证执行顺序
- 增加了
waveOut.Dispose(),优化资源管理避免内存泄漏
内容的提问来源于stack exchange,提问作者wellumies
相关产品推荐
相关产品推荐

