By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,274 Members | 1,823 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,274 IT Pros & Developers. It's quick & easy.

Can't enable a Timer in a Speech Recognized handler

P: n/a
Note that although this involves SAPI, it is more a question about Timers
and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to enable
a Timer. It would not do it. If I bring this same code outside this event
handler, it works just fine.

Is this normal?

Oct 8 '07 #1
Share this Question
Share on Google+
16 Replies


P: n/a
>Note that although this involves SAPI, it is more a question about Timers
>and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to enable
a Timer. It would not do it. If I bring this same code outside this event
handler, it works just fine.
And the code you've used it what?

You need to tell us a bit more!

Dave
Oct 9 '07 #2

P: n/a

"Peter Oliphant" <pe********@hotmail.comwrote in message
news:6F**********************************@microsof t.com...
Note that although this involves SAPI, it is more a question about Timers
and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to
enable a Timer. It would not do it. If I bring this same code outside this
event handler, it works just fine.

Is this normal?
Which "Timer"? .NET has at least three different classes named Timer.
Oct 9 '07 #3

P: n/a
I wish this newsgroup had an ability to at least attach a text file with
code. My code to demonstrate this situation is too long, and this newsgroup
tends to reformat the text in a bad way if the line is too long.

But, I'll try to explain it a bit more. Assume in the following that 'timer'
is set up with an interval and event handler:

System::Windows::Forms::Timer^ timer = gcnew Timer() ;

void Handler( Object^, SpeechRecognizedEventArgs^ e )
{
timer->Enable ; // problem!
}

That is, if I try to launch a timer inside the 'recognized speech' handler
it doesn't enable the timer. I believe it also locks out the timer from then
on (timer no longer responds to any commands). If this code is placed
outside of the handler, it launches the timer just fine.

FYI, using MS VS VC++ 2008 Express (Beta 2) with .NET Framework 3.5 on a
Vista machine. (SAPI 5.3 ala Vista). Managed (/cli) code generation.

I have a workaround, but it's not wonderful. I create an external 'master'
timer that polls whether other timers should be turned on via their
individual flags, and then set the flag of the timer to be launched in the
above handler instead. The disadvantage of course is that this adds an
unpredictable additonal lag (since it can make the request by setting the
timer flag at any point in the master timer's interval), although it is
short by human terms.

I tried moving this to the Recognition Completed handler of the speech
recognizer thinking perhaps it was the extensive recognition processing that
caused the problem. But that handler won't launch a timer either.

Hope that helps in the info department. This could be a problem or a
feature. If a problem, it could be part of SAPI or VC++.It could be a bug in
my code, but I've seen this happen two different ways (or NOT happeneing, if
you will), so this is not likely. I'm wondering if it is just disallowed in
general to launch a System Timer from an (any?) event handler. Can a Timer
handler launch another Timer, for instance?

Don't hesitate to ask if you want some specific questions asked...

Thanks!

[==Peter==]
"David Lowndes" <Da****@example.invalidwrote in message
news:l9********************************@4ax.com...
Note that although this involves SAPI, it is more a question about Timers
and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to
enable
a Timer. It would not do it. If I bring this same code outside this event
handler, it works just fine.

And the code you've used it what?

You need to tell us a bit more!

Dave

Oct 9 '07 #4

P: n/a
>But, I'll try to explain it a bit more. Assume in the following that 'timer'
>is set up with an interval and event handler:

System::Windows::Forms::Timer^ timer = gcnew Timer() ;

void Handler( Object^, SpeechRecognizedEventArgs^ e )
{
timer->Enable ; // problem!
Is that actually:
timer->Enabled = true;
?
>That is, if I try to launch a timer inside the 'recognized speech' handler
it doesn't enable the timer.
Is there any sign of an exception being raised in the output window?
>If this code is placed
outside of the handler, it launches the timer just fine.
So are you saying that if you just call timer->Enabled = true; for
that same timer object from elsewhere in your code (with no other
changes), it's OK? I'm stumped in that case. I don't know enough about
the timer implementation to offer an explanation of that behaviour.

Dave
Oct 9 '07 #5

P: n/a
"Peter Oliphant" <po*******@roundtripllc.comwrote in message
news:ux**************@TK2MSFTNGP04.phx.gbl...
Hope that helps in the info department. This could be a problem or a
feature. If a problem, it could be part of SAPI or VC++.It could be a bug
in my code, but I've seen this happen two different ways (or NOT
happeneing, if you will), so this is not likely. I'm wondering if it is
just disallowed in general to launch a System Timer from an (any?) event
handler. Can a Timer handler launch another Timer, for instance?
I'd bet a few cents that the "bug" is not in SAPI. Of course, I could be
wrong.

I don't know that it is your problem, but every time that I've seen people
report "problems" in the SAPI groups with "events" not firing it has to do
with the fact that the host application does not pump messages. Underlying
SAPI is all that COM gunk which persists in using window messages as an IPC
mechanism in the 21st century which I think (I should point out that I'm on
the lunatic fringe*) should have gone out with 16 bit Windows.

That said, I don't know what the speech classes in the .Net framework do.
Mine wrap native C++/Win32 code. ;-)

Regards,
Will
www.ivrforbeginners.com

* In my own native SAPI applications I use a Win32 synchronization object -
an event handle - to signal the completion of operations so that I don't
have to punp messages. It's a lot more work.
Oct 9 '07 #6

P: n/a
Is that actually:
timer->Enabled = true;
yup, typo. Not lifted from my code since it's too big, so I just did that
from memory. :)
Is there any sign of an exception being raised in the output window?
Nope, it just does nothing. However, future attempts to use the timer no
longer work from anywhere.
So are you saying that if you just call timer->Enabled = true; for
that same timer object from elsewhere in your code (with no other
changes), it's OK? I'm stumped in that case. I don't know enough about
the timer implementation to offer an explanation of that behaviour
Yup. One possibility is this is just not allowed. An event is probably
similar to an 'interrupt', and some things can be dangerous if launched from
them. That's my guess.

I might try to write a truly reduced version of this behavior and post the
results to make sure it's not ME... :)

[==Peter==]

"David Lowndes" <Da****@example.invalidwrote in message
news:2i********************************@4ax.com...
But, I'll try to explain it a bit more. Assume in the following that
'timer'
is set up with an interval and event handler:

System::Windows::Forms::Timer^ timer = gcnew Timer() ;

void Handler( Object^, SpeechRecognizedEventArgs^ e )
{
timer->Enable ; // problem!

Is that actually:
timer->Enabled = true;
?
>>That is, if I try to launch a timer inside the 'recognized speech' handler
it doesn't enable the timer.

Is there any sign of an exception being raised in the output window?
>>If this code is placed
outside of the handler, it launches the timer just fine.

So are you saying that if you just call timer->Enabled = true; for
that same timer object from elsewhere in your code (with no other
changes), it's OK? I'm stumped in that case. I don't know enough about
the timer implementation to offer an explanation of that behaviour.

Dave

Oct 9 '07 #7

P: n/a
I'd bet a few cents that the "bug" is not in SAPI. Of course, I could be
wrong.
I've programmed long enough that I have the exact same instincts. I first
and foremost assume it's a problem either with a bug/typo in my code or a
misconception on my part (usually due to incomplete information on the
subject).

But this seems pretty cut and dried. I took the code that the event executes
(which I saw it get to ala a breakpoint experiment), took it outside the
event, and it worked perfectly. Inside, it doesn't launch the timer and the
timer no longer works. And no errors are ever reported in build or
execution.

It just might be a restrictions to what can be done in an event (since it is
like an interrupt). But it seems kind of weird that a Timer can't be
launched from event handlers (maybe any event handler, anyone have a
counter-example?). The only thing that makes me wonder about this is that no
errors are ever reported and it hangs the timer instead of doing absolutely
nothing. If this was intended behavior (on non-behavior if you will), I
would think it would do one or not the other.

Tonight I might build a tiny project that demonstrates this behavior, and
I''ll report back if this is true or if I'm an idiot (of course those are
not mutually exclusive possibilities...lol)...

[==Peter==]

"William DePalo [MVP VC++]" <wi***********@mvps.orgwrote in message
news:uO****************@TK2MSFTNGP05.phx.gbl...
"Peter Oliphant" <po*******@roundtripllc.comwrote in message
news:ux**************@TK2MSFTNGP04.phx.gbl...
>Hope that helps in the info department. This could be a problem or a
feature. If a problem, it could be part of SAPI or VC++.It could be a bug
in my code, but I've seen this happen two different ways (or NOT
happeneing, if you will), so this is not likely. I'm wondering if it
is just disallowed in general to launch a System Timer from an (any?)
event handler. Can a Timer handler launch another Timer, for instance?

I'd bet a few cents that the "bug" is not in SAPI. Of course, I could be
wrong.

I don't know that it is your problem, but every time that I've seen people
report "problems" in the SAPI groups with "events" not firing it has to do
with the fact that the host application does not pump messages. Underlying
SAPI is all that COM gunk which persists in using window messages as an
IPC mechanism in the 21st century which I think (I should point out that
I'm on the lunatic fringe*) should have gone out with 16 bit Windows.

That said, I don't know what the speech classes in the .Net framework do.
Mine wrap native C++/Win32 code. ;-)

Regards,
Will
www.ivrforbeginners.com

* In my own native SAPI applications I use a Win32 synchronization
object - an event handle - to signal the completion of operations so that
I don't have to punp messages. It's a lot more work.

Oct 9 '07 #8

P: n/a
OK, I've duplicated the problem in a little bit of code. I've put it below,
you must excuse any line-wrap.

If you want to see, create a console project.Place the code I have below the
Project.CPP file (the one with main()).

Be sure to add System.Speech as a reference, and set it up tp target .NET
Framework 3.5. This code will also likely only work on a Windows VISTA
machine (SAPI 5.3).

Describing the code:

In a 'globals' class it creates a Timer and a SpeechRecognitionEngine (that
recognizes 'yes' or 'no'). Say 'yes' or 'no' into the microphone, and he
Engine's Completed handler writes 'enable timer' to the console and enables
the timer. The Timer should after that write 'tick!' to the display 4 times
a second after that.

What happens is that you will see the 'enable timer' message, proving the
Completed handler fired and enabled Timer, but the 'Tick's never show up
indicating the Timer never fires!

Thus, whether a restriction or a bug, a Timer can't be enabled successfully
in any Speech Recognition event handler (this happens with all of them, I'm
just demonstrting Completed here).

Here is the code:

//------------------------

#include "stdafx.h"

#using <mscorlib.dll>
#using <System.DLL>
#using <System.Windows.Forms.DLL>

using namespace System::Windows::Forms ;
using namespace System ;
using namespace System::Speech::Recognition ;

typedef EventHandler<RecognizeCompletedEventArgs^Speech_Co mpleted_Handler
;
typedef System::Windows::Forms::Timer System_Timer ;

ref class globals
{
public:
static globals()
{
Timer = gcnew System::Windows::Forms::Timer() ;
Timer->Tick += gcnew EventHandler(&globals::Tick_Handler ) ;
Timer->Interval = 100 ;
Engine = gcnew SpeechRecognitionEngine() ;
Engine->SetInputToDefaultAudioDevice() ;
Engine->RecognizeCompleted += gcnew Speech_Completed_Handler(
&globals::Completed_Handler ) ;
Choices^ choices = gcnew Choices ;
choices->Add( "yes" ) ;
choices->Add("no" ) ;
Grammar^ grammar = gcnew Grammar(choices) ;
Engine->LoadGrammar(grammar) ;
}

static void Completed_Handler(Object^,RecognizeCompletedEventA rgs^)
{
Console::WriteLine( "enable timer" ) ;
Timer->Enabled = true ;
}

static void Tick_Handler( System::Object^,EventArgs^ )
{
Console::WriteLine( "tick!" ) ;
}

static SpeechRecognitionEngine^ Engine ;
static System::Windows::Forms::Timer^ Timer ;
} ;

int main(array<System::String ^^args)
{
Console::WriteLine("Speak!");
globals::Engine->RecognizeAsync() ;
Form^ form = gcnew Form() ;
Application::Run( form ) ;
return 0;
}

//------------------------

[==Peter==]

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:e%***************@TK2MSFTNGP02.phx.gbl...
>
"Peter Oliphant" <pe********@hotmail.comwrote in message
news:6F**********************************@microsof t.com...
>Note that although this involves SAPI, it is more a question about Timers
and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to
enable a Timer. It would not do it. If I bring this same code outside
this event handler, it works just fine.

Is this normal?

Which "Timer"? .NET has at least three different classes named Timer.
Oct 10 '07 #9

P: n/a
I've noticed something, so here's some more info on the behavior. This
message comes up in the Ouput window instead of the Timer firing:

"Loaded 'C:\Windows\System32\msxml3.dl"
"First-chance exception at 0x7611b09e in PAO_Recognition_Quirk.exe:
0x0000071A: The remote procedure call was cancelled."

[PAO_Recognition_Quirk.exe is the exacutable file's name for the project]

which I believe this is somehow telling me that my Timer is no-workie... :)

[==Peter==]

"Peter Oliphant" <pe********@hotmail.comwrote in message
news:EC**********************************@microsof t.com...
OK, I've duplicated the problem in a little bit of code. I've put it
below, you must excuse any line-wrap.

If you want to see, create a console project.Place the code I have below
the Project.CPP file (the one with main()).

Be sure to add System.Speech as a reference, and set it up tp target .NET
Framework 3.5. This code will also likely only work on a Windows VISTA
machine (SAPI 5.3).

Describing the code:

In a 'globals' class it creates a Timer and a SpeechRecognitionEngine
(that recognizes 'yes' or 'no'). Say 'yes' or 'no' into the microphone,
and he Engine's Completed handler writes 'enable timer' to the console and
enables the timer. The Timer should after that write 'tick!' to the
display 4 times a second after that.

What happens is that you will see the 'enable timer' message, proving the
Completed handler fired and enabled Timer, but the 'Tick's never show up
indicating the Timer never fires!

Thus, whether a restriction or a bug, a Timer can't be enabled
successfully in any Speech Recognition event handler (this happens with
all of them, I'm just demonstrting Completed here).

Here is the code:

//------------------------

#include "stdafx.h"

#using <mscorlib.dll>
#using <System.DLL>
#using <System.Windows.Forms.DLL>

using namespace System::Windows::Forms ;
using namespace System ;
using namespace System::Speech::Recognition ;

typedef EventHandler<RecognizeCompletedEventArgs^>
Speech_Completed_Handler ;
typedef System::Windows::Forms::Timer System_Timer ;

ref class globals
{
public:
static globals()
{
Timer = gcnew System::Windows::Forms::Timer() ;
Timer->Tick += gcnew EventHandler(&globals::Tick_Handler ) ;
Timer->Interval = 100 ;
Engine = gcnew SpeechRecognitionEngine() ;
Engine->SetInputToDefaultAudioDevice() ;
Engine->RecognizeCompleted += gcnew Speech_Completed_Handler(
&globals::Completed_Handler ) ;
Choices^ choices = gcnew Choices ;
choices->Add( "yes" ) ;
choices->Add("no" ) ;
Grammar^ grammar = gcnew Grammar(choices) ;
Engine->LoadGrammar(grammar) ;
}

static void Completed_Handler(Object^,RecognizeCompletedEventA rgs^)
{
Console::WriteLine( "enable timer" ) ;
Timer->Enabled = true ;
}

static void Tick_Handler( System::Object^,EventArgs^ )
{
Console::WriteLine( "tick!" ) ;
}

static SpeechRecognitionEngine^ Engine ;
static System::Windows::Forms::Timer^ Timer ;
} ;

int main(array<System::String ^^args)
{
Console::WriteLine("Speak!");
globals::Engine->RecognizeAsync() ;
Form^ form = gcnew Form() ;
Application::Run( form ) ;
return 0;
}

//------------------------

[==Peter==]

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:e%***************@TK2MSFTNGP02.phx.gbl...
>>
"Peter Oliphant" <pe********@hotmail.comwrote in message
news:6F**********************************@microso ft.com...
>>Note that although this involves SAPI, it is more a question about
Timers and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to
enable a Timer. It would not do it. If I bring this same code outside
this event handler, it works just fine.

Is this normal?

Which "Timer"? .NET has at least three different classes named Timer.
Oct 10 '07 #10

P: n/a
"Which "Timer"? .NET has at least three different classes named Timer. "

I got to thinking. Maybe this is the problem. Maybe I'm using the wrong
flavor of Timer. I'm using the System::Windows::Form::Timer, which now that
I think of it, is an 'old' Timer class.

Is there maybe a new-and-improved managed Timer class I should look at? I
All I need is one I can enable and disable, set its interval in
milliseconds, and for it to have tick event. I guess to distinguish it I
need it's full 'namespace' and any headers required.

Thanks!

[==Peter==]
[==Peter==]

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:e%***************@TK2MSFTNGP02.phx.gbl...
>
"Peter Oliphant" <pe********@hotmail.comwrote in message
news:6F**********************************@microsof t.com...
>Note that although this involves SAPI, it is more a question about Timers
and event handlers.

I wrote a Speech Recognize handler (SAPI), and put some code in it to
enable a Timer. It would not do it. If I bring this same code outside
this event handler, it works just fine.

Is this normal?

Which "Timer"? .NET has at least three different classes named Timer.
Oct 10 '07 #11

P: n/a
>I've noticed something, so here's some more info on the behavior. This
>message comes up in the Ouput window instead of the Timer firing:

"Loaded 'C:\Windows\System32\msxml3.dl"
"First-chance exception at 0x7611b09e in PAO_Recognition_Quirk.exe:
0x0000071A: The remote procedure call was cancelled."
Is the SAPI callback run on a different thread perhaps?

Dave
Oct 10 '07 #12

P: n/a
"Is the SAPI callback run on a different thread perhaps?"

The code I listed is the entire program. I didn't setup anything specific
except making sure it targets .NET Framework 3.5 and making System::Speech a
reference. And this must be run on a machine using Windows Vista, but might
work on an XP machine for which SAPI has been manually installed.

So to answer your question, I don't really know, but I didn't write anything
special to run it in a separate thread if that is what is happening.

[==Peter==]

"David Lowndes" <Da****@example.invalidwrote in message
news:3p********************************@4ax.com...
I've noticed something, so here's some more info on the behavior. This
message comes up in the Ouput window instead of the Timer firing:

"Loaded 'C:\Windows\System32\msxml3.dl"
"First-chance exception at 0x7611b09e in PAO_Recognition_Quirk.exe:
0x0000071A: The remote procedure call was cancelled."

Is the SAPI callback run on a different thread perhaps?

Dave

Oct 10 '07 #13

P: n/a
>"Is the SAPI callback run on a different thread perhaps?"
>
So to answer your question, I don't really know
You can find out if you run it under the debugger and check what
thread is active when you hit the callback.

I was offering it as a suggestion as to the cause of the error which I
originally suspected might have been showing up in the output window.

Dave
Oct 10 '07 #14

P: n/a
You can find out if you run it under the debugger and check what
thread is active when you hit the callback.
Where do I look in the GUI (during a debug session) to find this
information? How is a thread identified/distinguished (to determine 'what
thread' I need to know how a thread is represented: thread 1? thread A?
thread ???), Should I set a breakpoint in the callback and then look for it?
And I assume you mean the RecognitionCompleted callback since the Tick
callback never fires.

Can't do this till I get home tonight since my work computer isn't a Vista
machine... :)
I was offering it as a suggestion as to the cause of the error which I
originally suspected might have been showing up in the output window.
Cool. And thanks for taking the time to respond, too! :)

[==Peter==]

"David Lowndes" <Da****@example.invalidwrote in message
news:74********************************@4ax.com...
"Is the SAPI callback run on a different thread perhaps?"

So to answer your question, I don't really know

You can find out if you run it under the debugger and check what
thread is active when you hit the callback.

I was offering it as a suggestion as to the cause of the error which I
originally suspected might have been showing up in the output window.

Dave

Oct 10 '07 #15

P: n/a
>Where do I look in the GUI (during a debug session) to find this
>information? How is a thread identified/distinguished (to determine 'what
thread' I need to know how a thread is represented: thread 1? thread A?
thread ???), Should I set a breakpoint in the callback and then look for it?
Yes, that's right - use the Threads pane.
>And I assume you mean the RecognitionCompleted callback since the Tick
callback never fires.
Yes - that's where I'd assume setting the Enabled property might be
throwing an exception.

Dave
Oct 10 '07 #16

P: n/a
On Oct 10, 1:33 pm, "Peter Oliphant" <peteroi...@hotmail.comwrote:
OK, I've duplicated the problem in a little bit of code. I've put it below,
you must excuse anyline-wrap.
Why make excuses?

Here is a simple tool* that will check line width
<http://www.physci.org/twc.jnlp>

* Uses the Java Plug-In - sandboxed (like an average
applet on a web page).

Andrew T.

Oct 12 '07 #17

This discussion thread is closed

Replies have been disabled for this discussion.