我有一個我想使用的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