Отменить синхронное распознавание речи

Как с помощью SAPI от MSDN отменить операцию синхронного распознавания речи или, по крайней мере, остановить ее немедленно?

Установка для ввода значения 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     
      }
}

person JackBarn    schedule 02.04.2015    source источник
comment
Вы могли получить исходный поток и вызвать в нем исключение, но этот вопрос объясняет, почему вам не следует этого делать. Можете ли вы объяснить, почему опция async не работает для вас, учитывая, что у нее есть особый метод отмены?   -  person James Thorpe    schedule 02.04.2015
comment
@JamesThorpe Поскольку мое приложение работает и настроено, операция Async будет дорогостоящей с точки зрения производительности   -  person JackBarn    schedule 02.04.2015
comment
По своей природе вы не можете отменить вызов синхронизации. Есть ли версии функций Beginxxx, Endxxx, которые вы могли бы использовать?   -  person John Taylor    schedule 02.04.2015
comment
@John Taylor Что вы имеете в виду под функциями   -  person JackBarn    schedule 02.04.2015
comment
Нет никакого смысла использовать Recognize (), если вы можете использовать RecognizeAsync (). Что тривиально отменяется с помощью RecognizeAsyncCancel ().   -  person Hans Passant    schedule 03.04.2015


Ответы (1)


В этой статье MSDN показано, как использовать 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();
    }
}
person John Taylor    schedule 02.04.2015
comment
Ответов только на ссылку недостаточно для stackoverflow. - person Sildoreth; 02.04.2015
comment
Хорошо, я добавлю немного ценности в ближайшее время, а не просто вырезать и вставить - person John Taylor; 02.04.2015
comment
Большое спасибо. Причина, по которой я не использовал Async, заключалась в том, что он позволял основному потоку продолжать работу, но я никогда об этом не думал. Я заменил Join() на Suspend() и теперь все работает так, как я хочу - person JackBarn; 03.04.2015