Timer Elapsed事件如何与高优先级线程竞争?

时间:2010-07-22 18:18:31

标签: c# multithreading timer

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

如何确保我的Timer操作以低优先级方式运行?

2 个答案:

答案 0 :(得分:2)

System.Timers.Timer的优点是你可以通过SynchronizingObject属性分配一个同步对象,然后利用它来运行Elapsed事件一个可以控制其优先级的线程。 / p>

只需将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); }
        }
    }
}

答案 1 :(得分:1)

可能最简单的方法是拥有一个“忙”标志(或计数),并且只要它不为零就忽略计时器滴答。

P.S。不建议更改线程优先级。几乎没有必要。