使用Azure Speech Service转写WAV音频时TextBox仅显示最后识别片段的问题求助
问题排查与解决方案
我一眼就看出问题所在了——你的SpeechRecognizer_Recognized方法每次都会新建StringBuilder并直接覆盖绑定的Text属性,导致之前的识别内容全部丢失,最终只显示最后一段结果!
问题根源分析
看你这段核心代码:
private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e) { var transcriptionStringBuilder = new StringBuilder(); // 每次触发事件都新建,之前的内容被清空 if (e.Result.Reason == ResultReason.RecognizedSpeech) { transcriptionStringBuilder.Append(e.Result.Text); // 仅添加当前识别的单段文本 Text = transcriptionStringBuilder.ToString(); // 直接覆盖原有Text内容 IsVisible = Visibility.Visible; } }
Recognized事件每次触发对应一段已确认的完整语音片段,但你每次都创建新的StringBuilder,只保留当前片段的内容,然后直接赋值给绑定的Text属性——这相当于每次都把之前的转写结果清空,自然最后只能看到最后一段识别内容。
另外还有个隐藏坑:Azure Speech SDK的事件回调是在后台线程触发的,WPF的UI控件只能在UI线程更新,直接赋值可能会引发线程异常,这个也要一并处理。
修复方案
1. 把StringBuilder改为类成员变量
在你的ViewModel或代码后台类中,定义一个全局的StringBuilder来累计所有识别结果:
// 类级别成员变量,保留所有转写内容 private readonly StringBuilder _transcriptionStringBuilder = new StringBuilder();
2. 修改Recognized事件处理逻辑
改成追加文本,并切换到UI线程更新绑定属性:
private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e) { if (e.Result.Reason == ResultReason.RecognizedSpeech) { // 追加当前识别的文本,添加换行让结果更易读 _transcriptionStringBuilder.AppendLine(e.Result.Text); // 切换到UI线程更新绑定属性,避免线程异常 Application.Current.Dispatcher.Invoke(() => { Text = _transcriptionStringBuilder.ToString(); IsVisible = Visibility.Visible; }); } }
3. (可选)重置转写内容(支持多次识别)
如果需要多次触发语音转写,记得在每次开始识别前清空累计的内容:
// 在调用StartContinuousRecognitionAsync之前执行 _transcriptionStringBuilder.Clear(); Text = string.Empty;
补充说明
Recognizing事件返回的是实时中间识别结果(可能会不断修正),而Recognized事件返回的是最终确认的完整片段,用Recognized来累计最终转写结果是正确的选择。- 必须通过
Dispatcher.Invoke更新UI,否则会因为跨线程操作控件抛出InvalidOperationException。
内容的提问来源于stack exchange,提问作者edu
相关产品推荐
相关产品推荐

