【问题标题】:Cancel Synchronous Speech Recognition取消同步语音识别
【发布时间】:2015-04-02 14:38:33
【问题描述】:

使用 MSDN 的 SAPI,如何取消同步语音识别操作,或者至少立即停止?

将输入设置为 null 会返回一个错误,指出在识别器正在识别时我不能这样做,并且不能选择使用异步识别。

下面是一个例子

class MainClass {

     static void Main( ) {
          SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine();
          recognizer.LoadGrammar(new DictationGrammar() );
          recognizer.SetInputToDefaultAudioDevice();
          recognizer.Recognize();
     }

     void MethodCalledFromOtherThread() {   
           //Since SpeechRecognitionEngine.Recognize() stops the current thread,
           //this method is called from a different thread.
           //I NEED the current thread to stop.

           //Here I want to Cancel recognizer.Recognize     
      }
}

【问题讨论】:

  • 可能能够获取原始线程并在其上抛出异常,但this question 说明了您不应该这样做的原因。你能解释一下为什么异步选项对你不起作用,因为它有一个特定的取消方法吗?
  • @JamesThorpe 我的应用程序的工作方式和设置方式,异步操作在性能方面的成本很高
  • 从本质上讲,您无法取消同步呼叫。有没有可以使用的函数的 Beginxxx、Endxxx 版本?
  • @John Taylor “函数”是什么意思
  • 当您可以使用RecognizeAsync() 时,使用Recognize() 毫无意义。使用 RecognizeAsyncCancel() 可以轻松取消。

标签: c# speech-recognition sapi


【解决方案1】:

MSDN article 展示了如何在没有线程的情况下异步使用 SAPI,并且您可以随时取消操作。

这是一个非常简单的例子,说明如何提前终止识别。

class Program
{
    private static bool _userRequestedAbort = false;

    // Indicate whether asynchronous recognition is complete.

    static void Main(string[] args)
    {
        // Create an in-process speech recognizer.
        using (SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine(new CultureInfo("en-US")))
        {
            // Create a grammar for choosing cities for a flight.
            Choices cities = new Choices(new string[] { "Los Angeles", "New York", "Chicago", "San Francisco", "Miami", "Dallas" });

            GrammarBuilder gb = new GrammarBuilder();
            gb.Append("I want to fly from");
            gb.Append(cities);
            gb.Append("to");
            gb.Append(cities);

            // Construct a Grammar object and load it to the recognizer.
            Grammar cityChooser = new Grammar(gb);
            cityChooser.Name = ("City Chooser");
            recognizer.LoadGrammarAsync(cityChooser);

            bool completed = false;

            // Attach event handlers.
            recognizer.RecognizeCompleted += (o, e) =>
            {
                if (e.Error != null)
                {
                    Console.WriteLine( "Error occurred during recognition: {0}", e.Error);
                }
                else if (e.InitialSilenceTimeout)
                {
                    Console.WriteLine("Detected silence");
                }
                else if (e.BabbleTimeout)
                {
                    Console.WriteLine("Detected babbling");
                }
                else if (e.InputStreamEnded)
                {
                    Console.WriteLine("Input stream ended early");
                }
                else if (e.Result != null)
                {
                    Console.WriteLine("Grammar = {0}; Text = {1}; Confidence = {2}", e.Result.Grammar.Name, e.Result.Text, e.Result.Confidence);
                }
                else
                {
                    Console.WriteLine("No result");
                }

                completed = true;
            };

            // Assign input to the recognizer and start an asynchronous
            // recognition operation.
            recognizer.SetInputToDefaultAudioDevice();

            Console.WriteLine("Starting asynchronous recognition...");
            recognizer.RecognizeAsync();

            // Wait for the operation to complete.
            while (!completed)
            {
                if (_userRequestedAbort)
                {
                    recognizer.RecognizeAsyncCancel();
                    break;
                }

                Thread.Sleep(333);
            }

            Console.WriteLine("Done.");
        }

        Console.WriteLine();
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

【讨论】:

  • 在 stackoverflow 上仅链接的答案是不够的。
  • 好的,我会尽快添加一些价值,而不仅仅是剪切和粘贴
  • 非常感谢。我不使用 Async 的原因是它允许主线程继续运行,但我从未想过这一点。我用Suspend() 替换了Join(),现在一切正常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 2018-04-17
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多