如何在C#中使用多线程时实现“等待”状态 [英] How to implement a 'wait' state when using multi-threading in C#
问题描述
我有一个类,我应用多线程。我想只允许1个线程'startSpeaking()'在一次。这是我的尝试:
I have a class that I am applying multi-threading to. I would like to only allow 1 thread to 'startSpeaking()' at one time. Here is my attempt:
class VoiceEffect
{
SpeechSynthesizer reader = new SpeechSynthesizer();
static readonly object _locker = new object();
public void createVoiceThread(string str)
{
Thread voicethread = new Thread(() => startSpeaking(str)); // Lambda Process
voicethread.IsBackground = true;
voicethread.Start();
}
public void startSpeaking(string str)
{
lock (_locker)
{
reader.Rate = -2; // Voice effects.
reader.Volume = 100;
reader.Speak(str);
}
}
}
c $ c> createVoiceThread()方法。它在另一个类中由类似的约定调用。例如
I am also calling createVoiceThread()
method from another class. It is called by a similar convention in another class. E.g.
class Program
{
static void Main(string[] args)
{
VoiceEffect ve = new VoiceEffect();
string text = "Hello world, how are you today? I am super-duper!!";
for( int i=0 ; i < 10 ; i++ )
{
ve.createVoiceThread(text);
ve.startSpeaking(text);
Thread.Sleep(1000);
}
}
}
我的问题是,修改此程序,以便在 startSpeaking()
被任何线程调用时,它每次只能播放单个语音模式。
My question is how can I modify this program so that when startSpeaking()
is called by any thread, that it only plays a single speech pattern at a time.
推荐答案
我知道这个问题是旧的,但如果我正确地理解你的问题(你希望所有的演讲顺序,如果它是在一个单一的线程)你可以这样做:
I know this question's old as hell, but if I'm understanding your question correctly (that you want all the speech done sequentially, as if it were done on a single thread) you can do something like this:
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
变量,这意味着没有语音提示将会彼此重叠,因为他们都必须等待,直到变量被清除中。我不能保证的是提示将被读取的顺序(即,控制消息处理队列),如果提交多个提示到队列,同时大声说出提示。无论哪种方式,这应该几乎工作。
This gives you a singleton class that will manage all threads, and all threads will share the _isCurrentlySpeaking
variable, which will mean that no speech prompts will ever overlap each other since they'll all have to wait until the variable is cleared before speaking. What I cannot guarantee is the order the prompts will be read (i.e., take control of the message-processing queue), if you submit multiple prompts to the queue while there's a prompt being spoken aloud already. Either way, this should pretty much work.
这篇关于如何在C#中使用多线程时实现“等待”状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!