在我的应用程序中,我有一个连续运行的线程。通过使用Thread.Sleep(),该函数每10分钟执行一次。
我需要能够在用户单击按钮时杀死此线程。我知道Thread.Abort()不可靠。我可以使用变量来停止线程,但由于它正在休眠,可能需要另外10分钟才能使线程自动停止。
有什么好的建议吗?
在我的应用程序中,我有一个连续运行的线程。通过使用Thread.Sleep(),该函数每10分钟执行一次。
我需要能够在用户单击按钮时杀死此线程。我知道Thread.Abort()不可靠。我可以使用变量来停止线程,但由于它正在休眠,可能需要另外10分钟才能使线程自动停止。
有什么好的建议吗?
以下是使用计时器执行工作的示例,正如Brian所建议的那样。根据需要使用开始/停止。在完成对象(Program)后清理它时,请确保调用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();
}
}
}
不要使用Thread.Sleep
,而是使用System.Threading.ManualResetEvent
。 WaitOne方法和Thread.Sleep
一样有一个超时时间,除非事件先被触发,否则您的线程将在该间隔内休眠,并且返回值会告诉您是否经过了该间隔还是事件已设置。
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()
{
//...
} }
DoWork()
所花费的时间。如果工作时间超过瞬间,计时将会出错。应该从(上次工作开始时间 + mTimeout)中减去当前时间;如果结果为负数,则根本不需要等待,直接循环回去(任务执行时间超过了mTimeout)。 - devstuff