首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

WinForm 引用 System.Speech 報「值不在預期範圍」:STAThread 與 MTAThread 衝突解決

     編輯:程式設計綜合問答

現象:保留 [STAThread] 時調用 SRE.SetInputToDefaultAudioDevice() 拋出異常;去掉則語音正常但其他窗體異常。

根因分析

  • System.Speech 底層調用 SAPI COM 組件,要求 MTA(多線程單元) 模式。
  • [STAThread] 強制主線程進入 STA(單線程單元),導致 COM 組件初始化失敗。
  • WinForm 其餘控件又依賴 STA 進行剪貼板、拖放等操作,去掉屬性會破壞它們。

解決方案:語音識別移至獨立 MTA 線程

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    // 啟動語音線程(MTA)
    Thread speechThread = new Thread(() => {
        // 必須在 MTA 線程中創建 SpeechRecognitionEngine
        var sre = new SpeechRecognitionEngine();
        sre.SetInputToDefaultAudioDevice();
        // ... 加載語法、註冊事件、RecognizeAsync
    });
    speechThread.SetApartmentState(ApartmentState.MTA); // 關鍵!
    speechThread.IsBackground = true;
    speechThread.Start();

    Application.Run(new MainForm()); // 主線程保持 STA
}

注意事項

  • 跨線程更新 UI 需用 Control.Invoke 或 SynchronizationContext。
  • 語音引擎生命週期隨線程結束,主程序退出前調用 sre.Dispose()。
  • .NET Core / .NET 5+ 建議改用 Microsoft.CognitiveServices.Speech (NuGet) 避免 COM 依賴。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved