我如何在一个单独的线程池System.Timer回调,或在一个专门的线程?
背景
我有使用System.Timer关键应用的轻量级显示器和无法弄清楚如何使回调不会在一个线程池,并在高优先级来操作。
造成这种情况的原因是:
如果关键应用程序无响应,线程池将发送取消标记,或Thread.Abort的,或者Win32的中止(即不运行终结),以悬吊线。
如果应用程序是CPU绑定,然后我的监视线程应以最高优先级运行,以防止拒绝服务攻击到我的显示器
线程池可能被耗尽,由于太多的线程,或的值MaxThreads过低
它不可能对一个线程在线程池设置优先级(据我所知)
因此,我认为它必须有一个计时器,它的回调在一个单独的线程,虽然我不知道如何实现这一目标。
如果这是通过创建一个单独的AppDomain可能,将在CLR还是让我在不同的AppDomain发布给其他线程的命令?
我想你可以通过做这个Thread.Sleep
上一个专门的线程。 那是:
void MonitorProc(object state)
{
while (!ShutdownSignaled)
{
Thread.Sleep(MonitorFrequency);
// Do monitor stuff here
}
}
如果设置线程优先级高,很可能是因为期望它会工作。 这不是一个很好的解决方案,但。
但是,你仍然有你的一个线程可能会崩溃,这将需要关闭整个应用程序的问题 - 包括显示器。
你可能会考虑显示器运行在高优先级,并发送指令到使用套接字或WCF或其他一些通信信道的主应用程序单独的应用程序。 这样一来,这款显示器会无法如果主应用程序崩溃而死。 你可以编写主应用程序在启动时自动启动监视器,如果它已不存在。
我不知道,不过,它是多么容易,你列出的条件都会执行。 让我们下去名单。
这里我就不明白你的第一点,除非它说,该计划可能崩溃。 在这种情况下,那么你应该只写一个单独的监控应用。
如果应用程序受限于CPU,显示器线仍然会得到一个时间片,如果所有线程都在相同的优先级。 即使其他线程都处于较高的优先级,你的显示器仍然会得到一个时间片,然后现在。 除非线程在实时优先级。 而且你不想这样做 。
如果您运行的线程,那么就用你的程序的一个根本问题 - 你可能你把它在生产之前应该已经发现了一个问题。
最可靠的方法来做到这一点的监控将是一个单独的应用程序。
我不知道的方式做到这一点使用System.Timer
。 然而,你可以求助于System.Windows.Forms.Timer
,以便有在您创建这种方式可以让你明确地设置其优先级的线程特定动作的定时器。
这工作,因为Tick
一个事件System.Windows.Forms.Timer
在创建它,通常在UI线程的线程总是触发,但你可以有一个线程没有UI运行的消息循环,并达到相同的。
查看是否以下是可以接受的:
static void Main(string[] args)
{
var monitorContext = new System.Windows.Forms.ApplicationContext();
var monitor = new Thread(Monitor) { Priority = ThreadPriority.Highest };
monitor.Start(monitorContext); // Start monitor
Thread.Sleep(5500); // ...
monitorContext.ExitThread(); // Terminates monitor
}
public static void Monitor(object context)
{
var timer = new System.Windows.Forms.Timer()
{
Enabled = true,
Interval = 1000
};
timer.Tick += new EventHandler(Monitor_Tick);
System.Windows.Forms.Application.Run(
(System.Windows.Forms.ApplicationContext)context);
}
private static void Monitor_Tick(object sender, EventArgs e)
{
Debug.WriteLine(
"{0}|{1}",
DateTime.UtcNow.ToString(),
Thread.CurrentThread.Priority);
}
你需要考虑的唯一的事情是,如果蜱事件被触发,同时仍在处理前一个那么它将被丢弃,所以一定要确保你在Tick事件做不采取比配置定时器的时间间隔越长。
文章来源: System.Timer always has a callback on a Threadpool thread. How can I make it non-Threadpool thread with high priority?