C# 计时器已过事件如何与高优先级线程竞争?

C# 计时器已过事件如何与高优先级线程竞争?,c#,multithreading,timer,C#,Multithreading,Timer,我有一个System.Timers.Timer对象要使用,但我不希望绑定到计时器的处理干扰正常到高优先级的线程。换句话说,我想说的是,只要没有其他东西在运行,我希望每5秒处理一次X 如何确保计时器操作以低优先级方式运行?最简单的方法可能是设置一个“忙”标志(或计数),并忽略计时器计时信号,只要它不为零 注意:不建议更改线程优先级。几乎没有必要这样做。System.Timers.Timer的好处在于,您可以通过SynchronizingObject属性分配一个同步对象,然后利用它运行已用事件,线程

我有一个System.Timers.Timer对象要使用,但我不希望绑定到计时器的处理干扰正常到高优先级的线程。换句话说,我想说的是,只要没有其他东西在运行,我希望每5秒处理一次X


如何确保计时器操作以低优先级方式运行?

最简单的方法可能是设置一个“忙”标志(或计数),并忽略计时器计时信号,只要它不为零


注意:不建议更改线程优先级。几乎没有必要这样做。

System.Timers.Timer的好处在于,您可以通过
SynchronizingObject
属性分配一个同步对象,然后利用它运行
已用事件,线程的优先级可以控制

只需将
elapsedenventreceiver
的一个实例分配给计时器的
SynchronizingObject
属性

免责声明:我很快就完成了,所以您需要添加自己的收尾工作,以使其更加健壮

公共类ElapsedEventReceiver:ISynchronizeInvoke
{
私有线程m_线程;
private BlockingCollection m_Queue=新建BlockingCollection();
公共ElapsedEventReceiver()
{
m_线程=新线程(运行);
m_Thread.Priority=ThreadPriority.bellownormal;
m_Thread.IsBackground=true;
m_Thread.Start();
}
私家车
{
while(true)
{
Message Message=m_Queue.Take();
message.Return=message.Method.DynamicInvoke(message.Args);
message.Finished.Set();
}
}
公共IAsyncResult BeginInvoke(委托方法,对象[]args)
{
消息消息=新消息();
message.Method=Method;
message.Args=Args;
m_Queue.Add(消息);
返回消息;
}
公共对象EndInvoke(IAsyncResult结果)
{
消息消息=作为消息的结果;
如果(消息!=null)
{
message.Finished.WaitOne();
返回消息。返回;
}
抛出新的ArgumentException(“结果”);
}
公共对象调用(委托方法,对象[]args)
{
消息消息=新消息();
message.Method=Method;
message.Args=Args;
m_Queue.Add(消息);
message.Finished.WaitOne();
返回消息。返回;
}
需要公共布尔调用
{
获取{return Thread.CurrentThread!=m_Thread;}
}
私有类消息:IAsyncResult
{
公共代表法;
公共对象[]Args;
公共对象返回;
公共对象状态;
public ManualResetEvent Finished=新的ManualResetEvent(false);
公共对象异步状态
{
获取{返回状态;}
}
公共WaitHandle异步WaitHandle
{
获取{return Finished;}
}
公共布尔同步完成
{
获取{return false;}
}
公共图书馆完工了
{
获取{return Finished.WaitOne(0);}
}
}
}

我要做的是确保我的应用程序不会影响服务器上的其他应用程序。我正在编写一个评测应用程序。更改其他应用程序的线程优先级可能会有问题,但降低自己应用程序的优先级几乎不会有什么害处@MichaelHedgpeth——但分析应用程序可能是一个反例@杰弗里:我不同意。线程的正确优先级排序是违反直觉的,Windows调度程序内置了动态优先级提升功能,手动调整线程优先级通常会适得其反。是的,手动提升优先级可能会适得其反,但如果您有一个进程希望在后台运行,而没有其他进程在运行,您知道,高优先级进程不会共享任何资源(当然,一旦释放了加载程序锁),那么降低优先级不太可能会造成任何损害。除非我真的错过了什么,这当然是可能的。我遗漏了什么?这个答案假设的一个重要信息是,在Windows上,只要高优先级线程可以运行(通常),低优先级线程就不会被安排运行。这意味着设置线程的优先级将实现您想要的。这一事实可能并不明显,因为有些人可能认为priorty只调整时间片的大小或其他方案。请注意,如果低优先级线程在一段时间内没有运行,Windows将避免“饥饿”低优先级线程,但这听起来并不是一个真正的问题。@Jeffrey:这一点很好。事实上,在我当前的示例中,这实际上可能是有问题的,因为用于执行的封送消息将开始堆积,可能会溢出队列。我会在有机会的时候修改这个。
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); }
        }
    }
}