问题陈述
我有一个工作线程,主要是扫描一个文件夹,进入其中的文件,然后休眠一段时间。扫描操作可能需要2-3秒钟,但不会更长。我正在寻找一种优雅地停止这个线程的方法。
澄清:我想在线程处于休眠状态时停止它,而不是在线程扫描时停止它。然而,问题在于我不知道线程的当前状态。如果它正在休眠,我希望它立即退出。如果它正在扫描,则希望在它尝试阻塞的那一刻退出。
解决方案尝试
起初我使用了Sleep和Interrupt。然后我发现Interrupt并不能真正中断Sleep - 它只在线程试图进入休眠时起作用。
所以我切换到了Monitor Wait&Pulse。然后我发现Pulse只在我实际处于Wait状态时起作用。所以现在我有一个线程,看起来像这样:
while (m_shouldRun)
{
try
{
DoSomethingThatTakesSeveralSeconds();
lock (this)
{
Monitor.Wait(this, 5000);
}
}
catch (ThreadInterruptedException)
{
m_shouldRun = false;
}
}
现在我需要编写停止函数。因此,我从以下内容开始:
public void Stop()
{
m_shouldRun = false;
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
但这个方法不起作用,因为我可能在线程工作时(而它没有等待)进行脉冲。所以我添加了中断:
public void Stop()
{
m_shouldRun = false;
thread.Interrupt();
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
另一个选择是使用:
public void Stop()
{
m_shouldRun = false;
while (!thread.Join(1000))
{
lock (this)
{
Monitor.Pulse(this);
}
}
}
问题
哪种方法是首选的?是否有第三种更可取的方法?