Azure语音转写任务执行时按钮禁用后无法恢复启用求助
问题:Azure语音转录任务结束后启动按钮无法恢复启用
问题场景
当前实现逻辑:启动任务时设置IsWorking = true并触发StartCommand.RaiseCanExecuteChanged()禁用按钮,期望Azure转录任务完成后设置IsWorking = false并恢复按钮启用。但实际执行后,按钮始终保持禁用状态。
问题根源
核心问题出在AzureTranscriptionService.ConvertToTextAsync方法中:
- 创建了
TaskCompletionSource<int>但从未触发其完成信号,导致Task.WaitAny(new[] { taskCompleteionSource.Task })一直阻塞,后续的await永远无法完成,StartAction中IsWorking = false和StartCommand.RaiseCanExecuteChanged()的代码根本不会执行。 SpeechRecognizer_SessionStopped事件仅处理了识别结果,没有通知任务完成。
修复步骤
- 在
SpeechRecognizer_SessionStopped事件中触发TaskCompletionSource的完成信号,让异步任务继续执行 - 将阻塞线程的
Task.WaitAny改为异步的await Task.WhenAny,避免占用线程资源 - 确保
IsWorking的状态变更能正确触发命令状态更新(当前代码中RaiseCanExecuteChanged已经能触发CanStartAction重新判断,无需额外实现INotifyPropertyChanged,但如果后续有UI绑定需求,建议给IsWorking添加属性变更通知)
修正后的关键代码
修正AzureTranscriptionService.ConvertToTextAsync及相关事件
public async Task ConvertToTextAsync( string FilePath, string Language, string WordDocName) { var config = SpeechConfig.FromSubscription(ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION); config.SpeechRecognitionLanguage = Language; var taskCompletionSource = new TaskCompletionSource<int>(); using var audioConfig = AudioConfig.FromWavFileInput(FilePath); using var speechRecognizer = new SpeechRecognizer(config, audioConfig); speechRecognizer.Recognizing += SpeechRecognizer_Recognizing; speechRecognizer.Recognized += SpeechRecognizer_Recognized; speechRecognizer.SessionStarted += SpeechRecognizer_SessionStarted; // 传递taskCompletionSource到事件处理方法 speechRecognizer.SessionStopped += (sender, e) => SpeechRecognizer_SessionStopped(sender, e, taskCompletionSource); await speechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false); // 替换为异步等待,避免阻塞 await Task.WhenAny(new[] { taskCompletionSource.Task }).ConfigureAwait(false); await speechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false); } // 修改SessionStopped事件方法,接收TaskCompletionSource private void SpeechRecognizer_SessionStopped(object? sender, SessionEventArgs e, TaskCompletionSource<int> taskCompletionSource) { Debug.WriteLine("Stepped"); var sb = new StringBuilder(); foreach (var item in Letters) { sb.Append(item); } // 触发任务完成信号,让异步流程继续 taskCompletionSource.SetResult(0); }
验证StartAction逻辑(无需修改,确保流程能走到最后)
private async void StartAction(object obj) { // ... 原有文件处理代码 ... IsWorking = true; StartCommand.RaiseCanExecuteChanged(); await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath, SelectedItem, DocumentName); // 现在这段代码会正常执行 IsWorking = false; StartCommand.RaiseCanExecuteChanged(); }
额外建议
- 避免使用
async void作为命令的执行方法(StartAction),建议改为async Task,如果你的Command支持异步执行(比如使用IAsyncCommand),这样能更好地处理异常和任务状态。 - 给
IsWorking属性添加INotifyPropertyChanged实现,方便后续UI直接绑定该状态显示加载提示。
内容的提问来源于stack exchange,提问作者edu
相关产品推荐
相关产品推荐

