You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# GUI中停止文本转语音(TTS)并解决按钮冻结问题

问题解决方案

原代码的核心问题

  • 使用SpeechSynthesizer.Speak()同步方法,会阻塞UI线程,导致按钮冻结,无法在朗读过程中触发停止操作。
  • 停止朗读时直接调用spe.Dispose()销毁合成器,后续无法再次启动朗读。
  • 按钮文本切换逻辑依赖同步朗读完成,朗读过程中无法触发停止分支的代码。

修改后的完整代码

using System;
using System.Windows.Forms;
using System.Speech.Synthesis;

namespace TalkBack
{
    public partial class Form1 : Form
    {
        private readonly SpeechSynthesizer _speechSynthesizer = new SpeechSynthesizer();

        public Form1()
        {
            InitializeComponent();
            // 订阅朗读完成事件,确保按钮状态正确恢复
            _speechSynthesizer.SpeakCompleted += SpeechSynthesizer_SpeakCompleted;
        }

        private void SpeechSynthesizer_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
        {
            // 朗读完成后将按钮文本改回Speak
            btn.Text = "Speak";
        }

        private void btn_Click(object sender, EventArgs e)
        {
            if (btn.Text == "Speak")
            {
                // 切换按钮状态为停止
                btn.Text = "Stop";
                // 使用异步朗读方法,不阻塞UI线程
                string textToSpeak = inputbox.Text.Trim();
                if (!string.IsNullOrEmpty(textToSpeak))
                {
                    _speechSynthesizer.SpeakAsync(textToSpeak);
                }
                else
                {
                    // 输入为空时恢复按钮状态
                    btn.Text = "Speak";
                    MessageBox.Show("请输入要朗读的文本");
                }
            }
            else
            {
                // 停止异步朗读
                _speechSynthesizer.SpeakAsyncCancelAll();
                // 切换按钮状态为开始
                btn.Text = "Speak";
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            // 窗体关闭时正确释放资源
            _speechSynthesizer.Dispose();
            base.OnFormClosing(e);
        }
    }
}

关键改动说明

  • 替换同步朗读为异步朗读:使用SpeakAsync()替代Speak(),避免阻塞UI线程,解决按钮冻结问题,同时允许在朗读过程中点击按钮触发停止操作。
  • 正确停止朗读:使用SpeakAsyncCancelAll()停止所有异步朗读任务,而不是直接销毁合成器,保证后续可以再次启动朗读。
  • 订阅SpeakCompleted事件:确保朗读正常完成后,按钮文本能自动恢复为"Speak",避免状态不一致。
  • 添加资源释放逻辑:在窗体关闭时调用Dispose()释放SpeechSynthesizer资源,符合.NET资源管理规范。
  • 增加输入校验:避免空文本导致的无效朗读操作。

内容的提问来源于stack exchange,提问作者MaxMouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:48:23