Как правильно утилизировать SpeechSynthesizer для асинхронного преобразования текста в речь? - PullRequest
1 голос
/ 14 марта 2019

У меня есть форма, и я хочу разрешить пользователю получать асинхронный вывод текста в речь на основе содержимого текстового поля при каждом нажатии кнопки. Для контекста эта форма запускается как часть «внутренней» функции C # в VoiceAttack , и это продолжение предыдущего вопроса . Этот фрагмент хорошо выполняет свою работу:

SpeechSynthesizer synth = new SpeechSynthesizer(); // Create new SpeechSynthesizer instance

// Function for asynchronous voicing of text with text-to-speech
public void VoiceText(string text)
{
    string MyVoice = null; // Initialize string for storing requested text-to-speech voice
    string DefaultVoice = null; // Initialize string for storing default Windows text-to-speech voice
    try // Attempt the following code...
    {
        synth.SpeakAsyncCancelAll(); // Cancels all queued, asynchronous, speech synthesis operations
        synth.Volume = 100; // Set the volume level of the text-to-speech voice
        synth.Rate = -2; // Set the rate at which text is spoken by the text-to-speech engine
        MyVoice = VA.GetText(">SDTTextToSpeechVoice") ?? "Not Set"; // Retrieve phonemes for processed text or set to null
        DefaultVoice = synth.Voice.Name; // Store the current default Windows text-to-speech voice
        if (MyVoice == "Default") // Check if requested voice name is "Default"
        {
            MyVoice = DefaultVoice; // Set MyVoice to the DefaultVoice
            VA.SetText(">SDTTextToSpeechVoice", MyVoice); // Redefine VoiceAttack text variable based on redefined MyVoice
        }
        synth.SelectVoice(MyVoice); // Set the voice for this instance of text-to-speech output
    }
    catch // Handle exceptions encountered in "try"
    {
        synth.SelectVoice(DefaultVoice); // Set the voice for this instance of text-to-speech output to the Windows default voice
        string VoiceList = null; // Initialize string variable for storing available text-to-speech voice names
        foreach (InstalledVoice v in synth.GetInstalledVoices()) // Loop through all available text-to-speech voices
            VoiceList += ", " + v.VoiceInfo.Name; // Add text-to-speech voice name to storage variable
        VA.WriteToLog("Text-to-speech voice '" + MyVoice + "' not found", "yellow"); // Output info to event log
        VA.WriteToLog("Valid TTS Voices = " + VoiceList.Trim(',', ' '), "yellow"); // Output info to event log
        VA.WriteToLog("Defaulting to current Windows text-to-speech voice (" + DefaultVoice + ")", "yellow"); // Output info to event log
    }
    synth.SpeakAsync(text); // Generate text-to-speech output asynchronously
}

// Function for disposing SpeechSynthesizer object
public void SpeechDispose()
{
    synth.Dispose(); // Releases resources tied to SpeechSynthesizer object
}

SpeechDispose() вызывается при закрытии формы. Я не могу заключить синтезатор в оператор using(), потому что голос звучит асинхронно (я хочу, чтобы пользователь не был вынужден ждать окончания голосового вызова, прежде чем можно будет снова нажать кнопку). Есть ли лучший способ убрать?

...