Я знаю, что этот вопрос устарел, но если я правильно понимаю ваш вопрос (что вы хотите, чтобы все выступления были выполнены последовательно, как если бы это было сделано в одном потоке), вы можете сделать что-то вроде этого:
static class VoiceEffect
{
SpeechSynthesizer reader = new SpeechSynthesizer();
private volatile bool _isCurrentlySpeaking = false;
/// <summary>Event handler. Fired when the SpeechSynthesizer object starts speaking asynchronously.</summary>
private void StartedSpeaking(object sender, SpeakStartedEventArgs e)
{ _isCurrentlySpeaking = true; }
/// <summary>Event handler. Fired when the SpeechSynthesizer object finishes speaking asynchronously.</summary>
private void FinishedSpeaking(object sender, SpeakCompletedEventArgs e)
{ _isCurrentlySpeaking = false; }
private VoiceEffect _instance;
/// <summary>Gets the singleton instance of the VoiceEffect class.</summary>
/// <returns>A unique shared instance of the VoiceEffect class.</returns>
public VoiceEffect GetInstance()
{
if(_instance == null)
{ _instance = new VoiceEffect(); }
return _instance;
}
/// <summary>
/// Constructor. Initializes the class assigning event handlers for the
/// SpeechSynthesizer object.
/// </summary>
private VoiceEffect()
{
reader.SpeakStarted += new EventHandler<SpeakStartedEventArgs>(StartedSpeaking);
reader.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(FinishedSpeaking);
}
/// <summary>Speaks stuff.</summary>
/// <param name="str">The stuff to speak.</param>
public void startSpeaking(string str)
{
reader.Rate = -2; // Voice effects.
reader.Volume = 100;
// if the reader's currently speaking anything,
// don't let any incoming prompts overlap
while(_isCurrentlySpeaking)
{ continue; }
reader.SpeakAsync(str);
}
/// <summary>Creates a new thread to speak stuff into.</summary>
/// <param name="str">The stuff to read.</param>
public void createVoiceThread(string str)
{
Thread voicethread = new Thread(() => startSpeaking(str)); // Lambda Process
voicethread.IsBackground = true;
voicethread.Start();
}
}
Это дает вам одноэлементный класс, который будет управлять всеми потоками, и все потоки будут иметь общую переменную _isCurrentlySpeaking
, что будет означать, что никакие речевые запросы никогда не будут перекрывать друг друга, так как им всем придется ждать, покапеременная очищается, прежде чем говорить.То, что я не могу гарантировать, - это порядок чтения подсказок (т. Е. Контроль над очередью обработки сообщений), если вы отправляете в очередь несколько подсказок, когда подсказка уже произносится вслух.В любом случае, это должно сработать.