在询问之前,我将首先展示一些代码......
public partial class Player : UserControl
{
ManualResetEvent _pauseEvent;
ManualResetEvent _stopEvent;
Thread t;
public Player()
{
InitializeComponent();
this.Disposed += (s, a) =>
{
Quit();
};
_pauseEvent = new ManualResetEvent(true);
_stopEvent = new ManualResetEvent(false);
// Creates the thread...
t = new Thread(StartText);
t.IsBackground = false;
// Starts with thread paused...
StopPlaying();
// Let's go!
t.Start();
}
public void StopPlaying()
{
Console.WriteLine("Ordered to stop");
_pauseEvent.Reset();
}
private void ResumePlaying()
{
Console.WriteLine("Ordered to resume");
_pauseEvent.Set();
}
public void Quit()
{
_pauseEvent.Set();
_stopEvent.Set();
}
public void SetText(string text, bool loop)
{
StopPlaying();
// Here we supose the thread would be stopped!!!! But it's not!!!
// But when I call StopPlaying() from a button on the form that
// contains this usercontrol, everything works as expected
...... Do some processing here .....
ResumePlaying();
}
private void StartText()
{
while (true)
{
_pauseEvent.WaitOne(Timeout.Infinite);
if (_stopEvent.WaitOne(0))
break;
do // While LOOP
{
... Do some process here .....
// Verifies if stop requested
if (!_pauseEvent.WaitOne(0))
{
Console.WriteLine("STOP REQUESTED");
break;
}
}
} while (LOOP);
}
}
}
我的问题是:
当我从包含此UserControl的窗体的按钮调用StopPlaying()时,在线程内部进行的测试会正确检测到,但是当我从SetText()方法调用StopPlaying时,它不起作用,就像事件一样没有重置。
顺便说一句,方法SetText()由另一个相同形式的按钮调用。
答案 0 :(得分:2)
您的StartText()
方法看起来有竞争条件。您已在单独的线程上运行StartText
,并且从主UI线程调用SetText()
,因此可能发生的事情是SetText()
正在重置然后设置_pauseEvent
在将控制权传递回另一个线程之前。因此,就StartText
而言,重置永远不会发生。