我需要一個定時器等價物,它將定期執行一些特定的動作(例如更新數據庫中的某些進度或檢查要在數據庫中執行的新作業)。使用等待句柄的條件性定期計時器
這些操作綁定到WaitHandle,它指定是否需要執行作業。所以基本上這可以是,例如,當數據庫中存在新實體並且觸發搜索這些新實體時從外部設置的AutoResetEvent。計時器是必要的,因爲我想限制查詢數量到數據庫。因此,如果有10個新通知到達,AutomaticResetEvent將只設置一次,並且對於所有這些通知也只有一個查詢。
我的第一次嘗試是這樣的:
class ConditionalScheduler
{
public void AddConditionalAction(WaitHandle handle, Action action)
{
lock (syncRoot)
{
handles.Add(handle);
actions.Add(handle, action);
}
}
private readonly object syncRoot = new object();
private readonly Dictionary<WaitHandle, Action> actions = new Dictionary<WaitHandle, Action>();
private readonly List<WaitHandle> handles = new List<WaitHandle>();
public void RunTimerLoop()
{
do
{
WaitHandle[] waitHandles = handles.ToArray();
int index = WaitHandle.WaitAny(waitHandles);
if (index >= 0)
{
WaitHandle handle = waitHandles[index];
Action action;
lock (syncRoot)
{
action = actions[handle];
}
action();
}
Thread.Sleep(5000);
} while (true);
}
這種方法的問題是,WaitHandle.WaitAny只會給我說是引發了第一次的WaitHandle的指數。所以如果我有兩個或更多的WaitHandles被觸發,那麼我將只執行第一個動作而不是其他的動作。
您是否有更好的設計來達到執行在指定時間段內觸發的所有操作所需的結果?如果它簡化了這個問題,我可以使用另一種通知機制而不是WaitHandles。
謝謝!
這看起來像會起作用。但我希望只有一個線程的解決方案......對我來說,使用2個線程似乎有點沉重。 – aKzenT 2011-05-13 09:11:35
打開窗口任務管理器並轉到性能選項卡,查看您的操作系統上有多少線程正在運行。我現在有832個。所以我認爲一個mroe不會那麼糟糕:D – 2011-05-13 09:15:36
和btw可以在一個線程中完成:如果將句柄添加到隊列中,然後不等待5000,如果有多於X個句柄要執行,則全部執行它們並然後等待5000 – 2011-05-13 09:18:31