在我的应用程序中,我有一个连续运行的线程。通过使用Thread.Sleep(),该函数每10分钟执行一次。
我需要能够在用户单击按钮时终止此线程。我知道Thread.Abort()不可靠。我可以使用一个变量来停止线程,但是因为它正在休眠,所以可能是线程杀死之前的另一个10分钟。
有什么想法吗?
答案 0 :(得分:9)
为什么不使用计时器每十分钟安排一次任务。这将在线程池线程上运行您的代码,因此您不必自己管理它。
有关详细信息,请参阅System.Threading.Timer课程。
答案 1 :(得分:4)
而不是Thread.Sleep
使用System.Threading.ManualResetEvent
。 WaitOne方法的暂停时间与Thread.Sleep
类似,除非首先触发事件,否则您的线程将在该时间间隔内休眠,并且返回值会告诉您是否已经过了时间间隔或事件已设置。
答案 2 :(得分:4)
所以这是一个样本,用户定时器按照Brian的建议完成工作。根据需要使用开始/停止。要完成后清理(程序)对象,请确保调用Dispose。
请注意,当您调用Stop时,它将阻止计时器再次触发,但是在执行timer_Elapsed处理程序的过程中仍然可能有一个工作线程,即停止计时器不会停止任何当前正在执行的工作线程。
using System;
using System.Timers;
namespace TimerApp
{
class Program : IDisposable
{
private Timer timer;
public Program()
{
this.timer = new Timer();
this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
this.timer.AutoReset = true;
this.timer.Interval = TimeSpan.FromMinutes(10).TotalMilliseconds;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
// TODO...your periodic processing, executed in a worker thread.
}
static void Main(string[] args)
{
// TODO...your app logic.
}
public void Start()
{
this.timer.Start();
}
public void Stop()
{
this.timer.Stop();
}
public void Dispose()
{
this.timer.Dispose();
}
}
}
答案 3 :(得分:3)
以Ben的回答为基础,这是帮助你的模式......
using System.Threading;
public class MyWorker {
private ManualResetEvent mResetEvent = new ManualResetEvent(false);
private volatile bool mIsAlive;
private const int mTimeout = 6000000;
public void Start()
{
if (mIsAlive == false)
{
mIsAlive = true;
Thread thread = new Thread(new ThreadStart(RunThread));
thread.Start();
}
}
public void Stop()
{
mIsAlive = false;
mResetEvent.Set();
}
public void RunThread()
{
while(mIsAlive)
{
//Reset the event -we may be restarting the thread.
mResetEvent.Reset();
DoWork();
//The thread will block on this until either the timeout
//expires or the reset event is signaled.
if (mResetEvent.WaitOne(mTimeout))
{
mIsAlive = false; // Exit the loop.
}
}
}
public void DoWork()
{
//...
} }
答案 4 :(得分:2)
一种可能性是不让它睡10分钟。让它睡10秒钟,然后每隔60分钟才能完成它的工作。然后在停止之前只有10秒的延迟。
除了:这不一定是最佳解决方案,但它可能是最快的实现方式。与所有可能性一样,在选择适合您的解决方案时,您应该进行成本/收益分析。
如果10秒仍太多,您可以放弃它,但请记住,将其放得太远会导致可能的性能影响。
你是不对的,你不应该从外面杀死线程,如果你碰巧在他们锁定了一些没有被释放的资源的情况下这通常是一个灾难的处方。线程应该始终对自己的资源负责,包括它们的生命周期。