Have you seen this thread?
SpeechRecognizer.Settings.InitialSilenceTimeout not working right
Question
I have a Windows Phone 8 app that uses the SpeechRecognizer class (not SpeechRecognizerUI) to do speech recognition. How do I cancel a session that is in progress? I don't see a cancel or stop method in the SpeechRecognizer class.
UPDATE: I want to give context to mparkuk's answer based on this MSDN thread:
SpeechRecognizer.Settings.InitialSilenceTimeout not working right
The way to cancel a speech recognition operation is to maintain a reference to the IAsyncOperation returned by the recognizer's IAsyncOperation call instead of "discarding it" by directly awaiting the RecoAsync() call to get the recognition result. I am including the code below in case the thread get's lost over time. The gist of cancelling a speech recognition session is to call the IAsyncOperation.Cancel() method.
private const int SpeechInputTimeoutMSEC = 10000;
private SpeechRecognizer CreateRecognizerAndLoadGrammarAsync(string fileName, Uri grammarUri, out Task grammarLoadTask)
{
// Create the recognizer and start loading grammars
SpeechRecognizer reco = new SpeechRecognizer();
// @@BUGBUG: Set the silence detection to twice the configured time - we cancel it from the thread
reco.Settings.InitialSilenceTimeout = TimeSpan.FromMilliseconds(2 * SpeechInputTimeoutMSEC);
reco.AudioCaptureStateChanged += recognizer_AudioCaptureStateChanged;
reco.Grammars.AddGrammarFromUri(fileName, grammarUri);
// Start pre-loading grammars to minimize reco delays:
reco.PreloadGrammarsAsync();
return reco;
}
/// <summary>
/// Recognize async
/// </summary>
public async void RecognizeAsync()
{
try
{
// Start recognition asynchronously
this.currentRecoOperation = this.recognizer.RecognizeAsync();
// @@BUGBUG: Add protection code and handle speech timeout programmatically
this.SpeechBugWorkaround_RunHangProtectionCode(this.currentRecoOperation);
// Wait for the reco to complete (or get cancelled)
SpeechRecognitionResult result = await this.currentRecoOperation;
this.currentRecoOperation = null;
// Get the results
results = GetResults(result);
this.CompleteRecognition(results, speechError);
}
catch (Exception ex)
{
// error
this.CompleteRecognition(null, ex);
}
// Restore the recognizer for next operation if necessary
this.ReinitializeRecogizerIfNecessary();
}
private void SpeechBugWorkaround_RunHangProtectionCode(IAsyncOperation<SpeechRecognitionResult> speechRecoOp)
{
ThreadPool.QueueUserWorkItem(delegate(object s)
{
try
{
bool cancelled = false;
if (false == this.capturingEvent.WaitOne(3000) && speechRecoOp.Status == AsyncStatus.Started)
{
cancelled = true;
speechRecoOp.Cancel();
}
// If after 10 seconds we are still running - cancel the operation.
if (!cancelled)
{
Thread.Sleep(SpeechInputTimeoutMSEC);
if (speechRecoOp.Status == AsyncStatus.Started)
{
speechRecoOp.Cancel();
}
}
}
catch (Exception) { /* TODO: Add exception handling code */}
}, null);
}
private void ReinitializeRecogizerIfNecessary()
{
lock (this.sync)
{
// If the audio capture event was not raised, the recognizer hang -> re-initialize it.
if (false == this.capturingEvent.WaitOne(0))
{
this.recognizer = null;
this.CreateRecognizerAndLoadGrammarAsync(...);
}
}
}
/// <summary>
/// Handles audio capture events so we can tell the UI thread we are listening...
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void recognizer_AudioCaptureStateChanged(SpeechRecognizer sender, SpeechRecognizerAudioCaptureStateChangedEventArgs args)
{
if (args.State == SpeechRecognizerAudioCaptureState.Capturing)
{
this.capturingEvent.Set();
}
}
------------------------------------- FROM THE MSDN THREAD -------------------
Credit: Mark Chamberlain Sr. Escalation Engineer | Microsoft Developer Support | Windows Phone 8
Regarding a cancellation mechanism, here is some suggested code from the developer.
The IAsyncOperation returned by RecognizeAsync has a Cancel function.
You have to:
1) Set the initial silence timeout to a large value (e.g.: twice the desired speech input timeout, in my case 10 seconds) reco.Settings.InitialSilenceTimeout = TimeSpan.FromMilliseconds(2 * SpeechInputTimeoutMSEC);
2) Store this.currentRecoOperation = this.recognizer.RecognizeAsync();
3) Kick off a worker thread to cancel the operation after 10 seconds if necessary. I didn’t want to take any chances so I also added code to re-initialize everything if a hang is detected. This is done by looking at whether the audio capture state changed to Capturing within a few seconds of starting the recognition.
Solution
Have you seen this thread?
SpeechRecognizer.Settings.InitialSilenceTimeout not working right