提高前進按鈕事件處理程序,如果我理解正確的問題,你希望用戶必須按「前進」按鈕只有一次。之後,程序應該自動繼續前進文本選擇,就像第一次按下按鈕時一樣,併爲每個新選擇的文本播放語音合成器。
如果是這樣的話,我相信這個可能工作:
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