• 0

.NET Speach .UnloadGrammer SLOW!


Question

Hello gang,

I am using the Speech.Recognition.GrammarBuilder to allow speech within an app. Everything works fine except when I unload grammer is takes up to 20 seconds.

For example; I have two sets of grammer. The first set contains navigation works (Up, Down, Select, etc) and the second set lists items (in this case names of files) When the user selects a new list the previous list of files is no longer needed so I need to remove them from the grammer.


If Not bMenuGrammer Is Nothing Then
Console.WriteLine("unload 1: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)
Me.bSpeechEngine.UnloadGrammar(bMenuGrammer)
Console.WriteLine("unload 2: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)
bMenuGrammer = Nothing
Console.WriteLine("unload 3: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)
End If
[/CODE]

It should be worth mentioning that there are some details in the Output window (and Im sure this will make me look stupid...)

[CODE]
unload 1: 30.45.247
The thread '<No Name>' (0x155c) has exited with code 0 (0x0).
The thread '<No Name>' (0x2360) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x27c8) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x155c) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x2360) has exited with code 0 (0x0).
The thread '<No Name>' (0x2198) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x2198) has exited with code 0 (0x0).
unload 2: 30.46.357
unload 3: 30.46.357
[/CODE]

The list can have as few as 1 item or maybe 100. Not a lot.

Between step 1 and 2 the wait can be 15 to 20 seconds

Any ideas?

Thanks

Link to comment
Share on other sites

8 answers to this question

Recommended Posts

  • 0

I'm not 100% sure what you are actually trying to do! Are you running/targeting .NET 4.5 or <4? I must admit I've never actually used the grammarbuilder class but I trust you have read up on the MSDN page at http://msdn.microsoft.com/en-us/library/system.speech.recognition.grammarbuilder.aspx ?

Link to comment
Share on other sites

  • 0

I'm not 100% sure what you are actually trying to do! Are you running/targeting .NET 4.5 or <4? I must admit I've never actually used the grammarbuilder class but I trust you have read up on the MSDN page at http://msdn.microsof...marbuilder.aspx ?

I'm using Framework 4.0 and it works, that is not the issue. The issue is the time it takes to unload a set of grammar.

Link to comment
Share on other sites

  • 0

I'm using Framework 4.0 and it works, that is not the issue. The issue is the time it takes to unload a set of grammar.

Yes I am aware of that but there was a major update to grammar in .NET 4 so I was curious to see if that could be causing problems. I really don't know why it would take so long, have fun.

Link to comment
Share on other sites

  • 0

Are you calling the RequestRecognizerUpdate method to pause the engine first as this article mentions?

Also, if you're removing stuff that's no longer needed you could probably do it asynchronously.

Admittedly, it's been a while since I've meddled with the speech engine. :)

Link to comment
Share on other sites

  • 0

Are you calling the RequestRecognizerUpdate method to pause the engine first as this article mentions?

Also, if you're removing stuff that's no longer needed you could probably do it asynchronously.

Admittedly, it's been a while since I've meddled with the speech engine. :)

Thanks... I found something similar late last night and I am about to check it out.

It's interesting to me that it takes so long to remove data. I'm curious as to the reasons... but not SO curious to dig that deep.

Thank you again.

Link to comment
Share on other sites

  • 0

Well, I have been playing with several attempts to improve the speed of the UnloadGrammar. There is a function on the SpeechRecognitionEngine called RecognizerUpdateReached that you are to call. What follows is my current solution and it allows the UI to be accessible while the grammar is unloaded.


Private Class UpdateGrammarRequest
Public RequestType As GrammarRequestType
Public Grammar As Grammar
Public Engine As SpeechRecognitionEngine
End Class

Private Enum GrammarRequestType
UnloadGrammar
LoadGrammar
End Enum


'THIS CODE IS CALLED WHEN NEW WORDS HAVE BEEN ADDED.
'IT THEN CALLS THE OBJECT BediaSpeechEngine's function (below)
Console.WriteLine("Before: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)

Dim objUpdateGrammerRequest = New UpdateGrammarRequest()

objUpdateGrammerRequest.RequestType = GrammarRequestType.UnloadGrammar
objUpdateGrammerRequest.Grammar = BediaMenuGrammer
objUpdateGrammerRequest.Engine = Me.BediaSpeechEngine

Me.BediaSpeechEngine.RequestRecognizerUpdate(objUpdateGrammerRequest)

Console.WriteLine("After: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)

Private Sub BediaSpeechEngine_RecognizerUpdateReached(sender As Object, e As RecognizerUpdateReachedEventArgs) Handles BediaSpeechEngine.RecognizerUpdateReached

Try
Dim request As UpdateGrammarRequest = e.UserToken

If Not request Is Nothing Then
Console.WriteLine("HERE 1: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)
Me.BediaSpeechEngine.UnloadGrammar(request.Grammar)

'-- Available Menus --
Dim MenuChoices As New System.Speech.Recognition.Choices()
Dim BediaGrammerBuilder As New Speech.Recognition.GrammarBuilder
Dim objMenuItem As MenuItem
Dim sValue As String
Dim sMenuText As String

For iMenus = 0 To (maryMenus.Count - 1)
objMenuItem = CType(maryMenus(iMenus), MenuItem)
MenuChoices.Add(New System.Speech.Recognition.SemanticResultValue(sMenuText, 4))
Next


BediaGrammerBuilder.Append(MenuChoices)
BediaMenuGrammer = Nothing
BediaMenuGrammer = New System.Speech.Recognition.Grammar(BediaGrammerBuilder)
Me.BediaSpeechEngine.LoadGrammarAsync(BediaMenuGrammer)

Console.WriteLine("HERE 2: " & Now.Minute.ToString & "." & Now.Second.ToString & "." & Now.Millisecond.ToString)

End If


Catch ex As Exception
LogException(ex)
Finally

End Try

End Sub
[/CODE]

Here are the results:

Minute . Second . Millisecond

Before: 14.22.92

After: 14.22.92

HERE 1: 14.37.959

HERE 2: 14.37.984

FIFTEEN SECONDS?!!!

At least the UI works, but having to wait for 15 seconds until function is available to load the new values is harsh.

Any thoughts?

Link to comment
Share on other sites

  • 0

Well let's interpret these results correctly first and foremost. The actual call to UnloadGrammer happens between the "HERE 1" and "HERE 2", and your numbers show that this takes about 25ms. Issuing the request to the speech recognition engine happens between the "before" and the "after", and those numbers show that no measurable time elapses then.

The 15 second difference appears to be the delay between the moment you issue the request and the moment the corresponding event handler is called by the speech recognition engine. This could be because it is busy with another long running operation. Have you issued a pause request before doing this as GreyWolf has pointed out?

Link to comment
Share on other sites

  • 0

Would you mind throwing this into your code before you try and stop the Engine:


BediaSpeechEngine.RecognizeAsyncStop();
[/CODE]

My theory is that you have something running in the background that's having to finish executing before you can unload it >.<

Link to comment
Share on other sites

This topic is now closed to further replies.