我有一个我想使用的System.Timers.Timer对象,但我不希望绑定到Timer的处理过程干扰正常到高优先级的线程。换句话说,我想说,只要没有别的东西在运行,我想每5秒钟处理一次X0 。。Timer Elapsed事件如何与高优先级线程竞争?
我怎么能保证我的定时器操作在一个低优先级的方式运行?
我有一个我想使用的System.Timers.Timer对象,但我不希望绑定到Timer的处理过程干扰正常到高优先级的线程。换句话说,我想说,只要没有别的东西在运行,我想每5秒钟处理一次X0 。。Timer Elapsed事件如何与高优先级线程竞争?
我怎么能保证我的定时器操作在一个低优先级的方式运行?
有关System.Timers.Timer的好处是您可以通过SynchronizingObject
属性分配同步对象,然后利用它来运行Elapsed
事件可以控制其优先级的线程。
的ElapsedEventReceiver
的实例只是分配给你的计时器的SynchronizingObject
财产。
免责声明:我掀起这件事非常快,所以你需要添加自己的收尾使其更加坚固。
public class ElapsedEventReceiver : ISynchronizeInvoke
{
private Thread m_Thread;
private BlockingCollection<Message> m_Queue = new BlockingCollection<Message>();
public ElapsedEventReceiver()
{
m_Thread = new Thread(Run);
m_Thread.Priority = ThreadPriority.BelowNormal;
m_Thread.IsBackground = true;
m_Thread.Start();
}
private void Run()
{
while (true)
{
Message message = m_Queue.Take();
message.Return = message.Method.DynamicInvoke(message.Args);
message.Finished.Set();
}
}
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
Message message = new Message();
message.Method = method;
message.Args = args;
m_Queue.Add(message);
return message;
}
public object EndInvoke(IAsyncResult result)
{
Message message = result as Message;
if (message != null)
{
message.Finished.WaitOne();
return message.Return;
}
throw new ArgumentException("result");
}
public object Invoke(Delegate method, object[] args)
{
Message message = new Message();
message.Method = method;
message.Args = args;
m_Queue.Add(message);
message.Finished.WaitOne();
return message.Return;
}
public bool InvokeRequired
{
get { return Thread.CurrentThread != m_Thread; }
}
private class Message : IAsyncResult
{
public Delegate Method;
public object[] Args;
public object Return;
public object State;
public ManualResetEvent Finished = new ManualResetEvent(false);
public object AsyncState
{
get { return State; }
}
public WaitHandle AsyncWaitHandle
{
get { return Finished; }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return Finished.WaitOne(0); }
}
}
}
也许最简单的方法是将有一个“忙”标志(或计数),而忽略只要它是非零的计时器滴答声。
P.S.不建议更改线程优先级。这几乎没有必要。
我想要做的是确保我的应用程序不会影响服务器上的其他应用程序。我在写一个分析应用程序。 – 2010-07-22 20:50:14
更改其他应用程序的线程优先级可能是个问题,但降低您自己的应用程序的优先级几乎不会有害。 @迈克尔Hedgpeth - 但一个分析应用程序可能是一个反例! – 2010-07-22 21:21:21
@杰弗里:我不同意。线程的正确优先级与直观相反,并且随着Windows调度程序内置的动态优先级提升,手动调整线程优先级往往适得其反。 – 2010-07-22 23:58:09
这个答案假定没有寻址的一条重要信息是,在Windows上,只要更高优先级的线程可以运行(通常),较低优先级的线程就不会被调度运行。这意味着设置线程的priorty将实现你想要的。这个事实可能并不明显,因为有些人可能认为priorty只调整时间片或其他方案的大小。请注意,如果Windows没有运行一段时间,Windows将避免“饿死”低优先级的线程,但听起来不像是一个问题。 – 2010-07-22 20:58:21
@杰弗里:好点。事实上,在我当前的例子中,实际上可能会产生问题,因为编组的消息可能会开始堆叠,可能会使队列溢出。当我有机会时,我会努力修改这个。 – 2010-07-22 21:07:35