Thanks for reporting this. I reproduced a bug on macOS where Stop() cancelled speech generation but audio that had already been generated could continue playing, particularly with long passages.
The fix will be included in the next release: SpeechSynthesiser.Stop promptly stops long passages on macOS.
You can keep Await w_SpeechSynthesiser.SpeakAsync(speech_text). Awaiting speech allows other button handlers to run, including your Stop button.
I’d also suggest two changes to your code:
- Move the
ExecuteJavaScript call inside Case "Start". Currently, clicking Stop also waits for JavaScript execution before reaching Stop().
- Reuse the synthesiser stored in your property. Creating a new instance on every Start can leave older instances speaking independently, while Stop only affects the newest one.
When you await SpeakAsync, stopping playback cancels its task, so catch TaskCancelledException to handle the user stopping speech normally.