/// <summary> /// Processes the word queue one by one /// the BGWorker Main loop /// </summary> private void SpeechWorker_DoWork(object sender, DoWorkEventArgs e) { bool doWork = !this.CancellationPending; string word = ""; // Loop while (true) { if (_workerWaitHandle.WaitOne(c_timeout)) { // signalled lock ( _words ) { if (_words.Count > 0) { word = _words.Dequeue( ); } } #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed _speakerWaitHandle.Reset( ); _speaker.SpeakAsync(word); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed // wait until spoken if (_speakerWaitHandle.WaitOne(s_timeout)) { // report a word said this.ReportProgress(++progressCount); } else { // run into a speech time out - either the word was tool long or something else prevented // the Speaker to signal end of speech // anyway try to recover and continue _speaker.Reset( ); } } // check for cancellation requested doWork &= (!this.CancellationPending); if (!doWork) { break; } // retrigger of there are words left if (_words.Count > 0) { _workerWaitHandle.Set( ); } } // finishing here _words.Clear( ); _workerWaitHandle.Reset( ); _speakerWaitHandle.Reset( ); _speaker?.Dispose( ); _speaker = null; // requires a new Init to proceed with Speaking }
/// <summary> /// cTor: /// </summary> public SpeechWorker( ) { _workerWaitHandle = new AutoResetEvent(false); _speakerWaitHandle = new AutoResetEvent(false); _speaker = new VoiceSynth(_speakerWaitHandle); this.WorkerSupportsCancellation = true; this.WorkerReportsProgress = true; this.DoWork += SpeechWorker_DoWork; }
/// <summary> /// Start the Speaker processing /// </summary> /// <param name="parameter">A parameter obj to use</param> public void InitSpeaker(object parameter) { if (!this.IsBusy) { // restart _speaker?.Dispose( ); _workerWaitHandle.Dispose( ); _speakerWaitHandle.Dispose( ); _workerWaitHandle = new AutoResetEvent(false); _speakerWaitHandle = new AutoResetEvent(false); _speaker = new VoiceSynth(_speakerWaitHandle); ClearWords( ); progressCount = 0; this.RunWorkerAsync(parameter); } else { throw new InvalidOperationException("Cannot InitSpeaker while Busy. Must Cancel first!"); } }