提高前进按钮事件处理程序,如果我理解正确的问题,你希望用户必须按“前进”按钮只有一次。之后,程序应该自动继续前进文本选择,就像第一次按下按钮时一样,并为每个新选择的文本播放语音合成器。
如果是这样的话,我相信这个可能工作:
private async void btnForward_Click(object sender, RoutedEventArgs e)
{
btnForward.Enabled = false;
while (true)
{
highlightText();
// NOTE: use whatever expression correctly identifies the state after
// you've called highlightText() when there's no more text to read.
// Here I've assumed that the selection will simply be empty, but
// if that's not right, presumably you have _some_ way to know that
// you're at the end of the text.
if (textArea.SelectedText == "")
{
break;
}
synth.SpeakAsyncCancelAll();
await Task.Run(() => synth.Speak(textArea.SelectedText));
}
btnForward.Enabled = true;
}
<编辑> 我跑一个小的测试,它似乎是在SpeakAsyncCancelAll()
方法不以立即干预随后调用Speak()
方法。另外,我发现确实取消了同步语音操作(即它会中断正在进行的对Speak()
的呼叫)。所以上述应该可以正常工作,甚至可以添加一个单独的按钮来取消操作,只需设置一个标志,然后调用SpeakAsyncCancelAll()
来中断当前的语音操作。
< /编辑>
从长期来看,一个更好的解决办法是实现上SpeechSynthesizer
类真正async
- 支持包装。不幸的是,据我所知,直接支持async
/await
的语音合成的唯一内置实现是SpeechSynthesizer
类的Windows Phone版本。但是,您应该可以编写自己的包装,使用TaskCompletionSource
以及处理各种SpeechSynthesizer
事件,以允许符合范例的异步方法。
请注意,在上述情况下,我禁用了该按钮,以便在处理上一个按钮按下时不再引发该事件。您不希望此代码具有并发迭代,所以我依靠UI状态来防止重新进入。
最后要注意的是,以上内容并没有提供任何方式让用户中断通过文本选择循环的进度。你在原始问题中没有提供足够的背景知道如何工作,所以我只是把它排除在外。但正如我上面提到的,你可以使用SpeakAsyncCancelAll()
方法中断同步语音操作,所以这会像设置一个标志那样简单,就像我上面提到的那样,调用cancel方法,然后在上面的循环中检查该标志以查看是否你需要提前爆发。
当你没有再次点击时再次提高'Click'事件是没有意义的。但是,除了这一点,假设它确实有效,结果会是什么?第二句话将被*立即*选择,并且'synth。SpeakAsyncCancelAll()'会取消第一句。 'SpeakAsync'的全部重点是,在讲话完成之前,你的代码的执行会继续*。 – hvd 2014-11-23 12:30:08
我认为第二句不会被_immediately_选中,因为'synth.SpeakAsync(textArea.SelectedText);'会导致事件等到它读取先前选择的句子。 – Hadi 2014-11-23 12:36:38
不,它没有。再次,这是'... Async'函数的全部:'Speak'方法等待。 SpeakAsync方法不会等待。这也是在文档中提到的。你可以通过添加一行像MessageBox.Show(“...”);'来轻松看到,并检查你在演讲过程中还是之后都会收到一个消息框。 – hvd 2014-11-23 12:55:37