События SpeechStarted / SpeechCompleted откладываются на неопределенный срок

#c# #text-to-speech #speech-synthesis

#c# #преобразование текста в речь #синтез речи

Вопрос:

У меня есть программа, которая включает реле, когда механизм синтеза начинает говорить, и выключает его, когда он заканчивает говорить. На компьютере, на котором я компилирую / работаю, он работает нормально, в 100% случаев. Двигатель начинает говорить, возникает событие, реле включается, двигатель перестает говорить, возникает событие, реле выключается. Никаких проблем. Просто!

Когда я устанавливаю программу на любой из своих ноутбуков, события возникают не сразу. Программа выдаст несколько подсказок, и в конечном итоге все события будут вызваны в кратком порядке. Похоже, что в этой задержке нет какой-либо закономерности. Один раз это было несколько секунд, обычно это больше минуты. Иногда события вообще не поднимаются (или они не поднимаются достаточно скоро, чтобы я мог их увидеть …)

Это происходит как с опубликованным приложением, так и в среде отладки в VS2013, но только на моих ноутбуках. Основной компьютер — Win8, один ноутбук — Win8, а другие ноутбуки — Win7. Мой основной компьютер и ноутбук win8 практически идентичны в том, что касается среды.

Я даже не знаю, с чего начать устранение неполадок. Я проверил (я думаю), что само событие не вызывается простым выводом некоторого текста на консоль с нулевыми условиями в любое время, когда оно вызывается. Через несколько минут я обычно получаю поток событий в консоли.

Я подумал, что, ВОЗМОЖНО, это проблема с производительностью (хотя ни один из этих ноутбуков не обладает недостаточной мощностью), но я действительно не знаю, как это подтвердить или как я мог бы ее устранить. Поместить весь движок TTS, включая события, в свой собственный поток? Возможно ли это вообще или практично? На самом деле не должно быть никаких проблем с замедлением или зависанием программы и каким-либо образом задержкой события — больше почти ничего не происходит.

Ниже приведен соответствующий код, с удалением большинства несвязанных материалов.

     TTS.SpeakStarted  = new EventHandler<SpeakStartedEventArgs>(TTS_SpeakStarted);
    TTS.SpeakCompleted  = new EventHandler<SpeakCompletedEventArgs>(TTS_SpeakCompleted);


    void TTS_SpeakStarted(object sender, SpeakStartedEventArgs e)
    {
        try {
            if (Properties.Settings.Default.relay_enabled)
                // do stuff
        }
        catch (Exception ex)
        {}
    }
    void TTS_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
    {
        try {
            if (Properties.Settings.Default.relay_enabled)
                // do stuff
        }
        catch (Exception ex)
        {}
    }
 

Ответ №1:

Мне не удалось заставить события SpeakStarted / SpeakCompleted функционировать должным образом.

Моя первая попытка найти решение состояла в том, чтобы поместить мой метод speak в его собственный поток и изменить его на синхронный. Таким образом, я мог бы иметь свой предыдущий код, а затем говорить, который блокировался бы до завершения, а затем мой последующий код. Это тоже не сработало. Speak заблокируется на тот же неопределенный промежуток времени, который потребовался для вызова событий, поэтому, хотя мой предшествующий код будет выполняться, мой последующий код — нет.

В конце концов, мое решение состояло в том, чтобы использовать событие StateChanged вместо SpeakStarted / SpeakCompleted . По какой-то причине событие StateChanged функционировало нормально, и я смог использовать это состояние, чтобы определить, когда движок начал говорить, и когда он был «готов», предположительно закончил говорить.