C# 检查控制计时器的线程的状态
我正在使用线程定期运行Windows服务中的线程。计时器如下:C# 检查控制计时器的线程的状态,c#,.net,multithreading,windows-services,timer,C#,.net,Multithreading,Windows Services,Timer,我正在使用线程定期运行Windows服务中的线程。计时器如下: private Timer _timer; public void Start() { _timer = new Timer(MainLoop, null, 0, Timeout.Infinite); } private void MainLoop(object state) { // Do something and then tell Timer to wait for a second _timer
private Timer _timer;
public void Start()
{
_timer = new Timer(MainLoop, null, 0, Timeout.Infinite);
}
private void MainLoop(object state)
{
// Do something and then tell Timer to wait for a second
_timer.Change(1000, Timeout.Infinite);
}
public void Stop()
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
}
我的问题是,我希望Windows服务能够监视循环正在运行的线程,并在发现它已停止时执行某些操作
以前我使用的是Thread.Sleep而不是计时器,这意味着一切都在单个线程中运行,而不是线程池中的单个线程,我可以查询线程的线程状态。现在我正在使用计时器,线程状态将停止,因为一旦计时器启动,线程将停止
那么,对于我来说,使用Threading.Timer时确认线程仍在运行的最佳方法是什么?让线程更新Windows服务可见的某个值,如果该值未更新,则表示线程已停止。我不知道还有什么其他方法可以监控计时器让线程更新Windows服务可见的某个值,如果该值未更新,则表示线程已停止。我不知道还有什么其他方法可以监控计时器您可以在contents main循环周围添加try finally块,以确保计时器始终重新启动
private void MainLoop(object state)
{
try
{
// Do something and then tell Timer to wait for a second
}
finally
{
_timer.Change(1000, Timeout.Infinite);
}
}
如果您仍然认为需要监视此方法的执行,则可以跟踪该方法上次启动的时间
private void MainLoop(object state)
{
_lastRunTime = DateTime.UtcNow;
try
{
// Do something and then tell Timer to wait for a second
}
finally
{
_timer.Change(1000, Timeout.Infinite);
}
}
然后,您可以使用_lastRunTime并将其与当前时间进行比较,以查看MainLoop的执行是否被挂起,或者计时器是否由于某种不明原因没有重新启动。您可以在内容MainLoop周围添加一个try finally块,以确保计时器始终重新启动
private void MainLoop(object state)
{
try
{
// Do something and then tell Timer to wait for a second
}
finally
{
_timer.Change(1000, Timeout.Infinite);
}
}
如果您仍然认为需要监视此方法的执行,则可以跟踪该方法上次启动的时间
private void MainLoop(object state)
{
_lastRunTime = DateTime.UtcNow;
try
{
// Do something and then tell Timer to wait for a second
}
finally
{
_timer.Change(1000, Timeout.Infinite);
}
}
然后,您可以使用_lastRunTime并将其与当前时间进行比较,以查看MainLoop的执行是否被挂起,或者计时器是否因为某种模糊的原因没有重新启动。我会采取另一种方法,创建您自己的线程,并使用回调来发出线程已完成的信号。回调会传回一个结果,主线程使用该结果来决定要做什么。你甚至不需要一个定时器来完成这项工作,尽管你可以用它来让你的工人在一段时间内开火 下面是一个示例,它使用WaitHandle向主管发出完成的信号
class Supervisor
{
EventWaitHandle waitHandle = new AutoResetEvent(false);
public bool Success { get; set; }
// launch worker thread and wait for result
public void Start()
{
while (true)
{
Thread thread = new Thread(() => { new Worker(new DoneDelegate(WorkerDone)).DoWork(); });
thread.IsBackground = true;
thread.Start();
waitHandle.WaitOne(); // wait for worker to finish
if (!Success) break; // handle error here
}
}
// callback for worker to report result
public void WorkerDone(bool successArg)
{
Success = successArg;
// wake up supervisor
waitHandle.Set();
}
}
public delegate void DoneDelegate(bool successArg);
class Worker
{
public DoneDelegate Done { get; set; }
public Worker(DoneDelegate doneArg)
{
Done = doneArg;
}
public void DoWork()
{
// simulate work and exception
Random rnd = new Random();
Thread.Sleep(1000);
try
{
int i = 10 / (1 - new Random().Next(5));
Done(true);
}
catch
{
Done(false);
}
}
}
我会采取另一种方法,创建自己的线程,并使用回调来表示线程已经完成。回调会传回一个结果,主线程使用该结果来决定要做什么。你甚至不需要一个定时器来完成这项工作,尽管你可以用它来让你的工人在一段时间内开火 下面是一个示例,它使用WaitHandle向主管发出完成的信号
class Supervisor
{
EventWaitHandle waitHandle = new AutoResetEvent(false);
public bool Success { get; set; }
// launch worker thread and wait for result
public void Start()
{
while (true)
{
Thread thread = new Thread(() => { new Worker(new DoneDelegate(WorkerDone)).DoWork(); });
thread.IsBackground = true;
thread.Start();
waitHandle.WaitOne(); // wait for worker to finish
if (!Success) break; // handle error here
}
}
// callback for worker to report result
public void WorkerDone(bool successArg)
{
Success = successArg;
// wake up supervisor
waitHandle.Set();
}
}
public delegate void DoneDelegate(bool successArg);
class Worker
{
public DoneDelegate Done { get; set; }
public Worker(DoneDelegate doneArg)
{
Done = doneArg;
}
public void DoWork()
{
// simulate work and exception
Random rnd = new Random();
Thread.Sleep(1000);
try
{
int i = 10 / (1 - new Random().Next(5));
Done(true);
}
catch
{
Done(false);
}
}
}
循环没有在任何特定线程上运行。当计时器周期结束时,MainLoop将在第一个可用的线程池线程上执行。如果您的程序中还有其他事情,MainLoop很可能在下次调用时在不同的线程上执行。您无法监视线程。下面的答案表明,使用最后一次运行时间可能是获得所需效果的最简单方法。主循环大部分时间都在做什么工作?处理文件?民意调查数据库?处理网络请求?执行计算任务?如果循环没有运行,你想做什么?@Jason主循环正在轮询数据库。我有两个服务在不同的服务器上运行,一个是主动的,一个是被动的。被动服务器通过TCP轮询主动服务,如果发现循环已停止,则应作为主动服务器接管。循环未在任何特定线程上运行。当计时器周期结束时,MainLoop将在第一个可用的线程池线程上执行。如果您的程序中还有其他事情,MainLoop很可能在下次调用时在不同的线程上执行。您无法监视线程。下面的答案表明,使用最后一次运行时间可能是获得所需效果的最简单方法。主循环大部分时间都在做什么工作?处理文件?民意调查数据库?处理网络请求?执行计算任务?如果循环没有运行,你想做什么?@Jason主循环正在轮询数据库。我有两个服务在不同的服务器上运行,一个是主动的,一个是被动的。被动式通过TCP轮询主动式服务,如果它发现循环已停止,那么它将作为主动式服务接管。我愚蠢地没有想到用try…catch来包装整个内容。我愚蠢地没有想到用try…catch来包装整个内容。我将采用Brian的答案,因为它更简单,但谢谢很多。我同意布赖恩的答案,因为它更简单,但非常感谢。