后台工作程序中包含的C#语音识别在取消

时间:2016-06-24 08:30:35

标签: c# speech-recognition

我的程序存在问题。有一个后台工作人员按下按钮开始,在这个工作者内部是一个包含一些语音识别代码的do循环,监视用户输入并显示它。该错误如下。如果您在停止/启动按钮上取消工作人员,语音识别引擎仍在等待另外一个输入,如果您在发言之前单击开始按钮以清除它,它现在将输出2个重复结果而不是一个。

语音识别代码的很大一部分是黑客斜线复制粘贴在一起工作,所以我不是非常熟悉它。

程序代码:http://pastebin.com/tBXKs5DT

感谢任何帮助

由于

1 个答案:

答案 0 :(得分:1)

出现问题是因为在循环到达取消检查之前松开了取消引用。为了解释这一点,我将采取一小部分代码:

_worker.DoWork += new DoWorkEventHandler((state, args) => {
   do {
        if (_worker.CancellationPending) {
           break;
        }
        //recognize spoken command
    } while (true);
});

当您点击停止按钮时,标记_worker以取消。但是循环很可能等着你说出来。只有在您说完后,循环才会继续并检查取消标记。

但是:当您按开始时,_worker引用将被覆盖并重复使用。那时你有两个循环运行。两者都看着同样的取消标志,它被设置回false。因此,如果您再说出来,它们都将处理您的语音命令,看到它们不必取消并继续。

要解决此问题,您的停止按钮应通过调用停止事件中_worker的{​​{3}}来中断工作线程(button2_click)。然后在do work代码中,您需要对.Interrupt进行try / catch。如果触发异常,则检查取消标志是否为真,如果是,则断开while循环。

一些额外的附注:

  • 使用RecognizeAsync可以更轻松地收听语音命令。看看interrupt exception
  • File.Exists已经返回了一个bool。在if语句中没有必要将它与true进行比较
  • 当写下更多的“你好世界”时。程序试图给一切正确的名称。该代码变得非常寻宝,其名称如" button1"

修改  中断的一个例子(免责声明:我手头没有VS,所以可能包含错别字)

设置取消标志并中断线程非常简单。假设您的线程(或基本上是线程的后台工作者)被称为_worker,它看起来有点像这样:

_worker.CancelAsync();
_worker.Interrupt(); 

这将在该dowork事件中触发中断异常。确保处理这些异常。在你的情况下,看起来像这样:

_worker.DoWork += new DoWorkEventHandler((state, args) => {
   do {
        try {
             if (_worker.CancellationPending) {
                 break;
             }
             //recognize spoken command
         } catch (ThreadInterruptedException) {
               if (_worker.CancellationPending) {
                 break;
               }
               //reaching this would be a odd situation. It means you interrupted your thread without canceling it. 
               //In your case this shouldn't happen, but there are cases in which you would want to support this
         }
    } while (true);
});