특정 작업 (예 : 데이터베이스의 일부 진행 업데이트 또는 데이터베이스에서 실행할 새 작업 확인)을 주기적으로 실행하는 타이머가 필요합니다.대기 핸들을 사용하는 조건부주기 타이머
이러한 작업은 작업을 실행해야하는지 여부를 지정하는 WaitHandle에 바인딩됩니다. 그래서 기본적으로 이것은 AutoResetEvent가 될 수 있습니다. AutoResetEvent는 데이터베이스에 새로운 Entity가있을 때 외부에서 설정되고 이러한 새로운 Entities에 대한 검색을 트리거합니다. 데이터베이스에 쿼리 수를 제한하기 때문에 타이머가 필요합니다. 따라서 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
Windows 작업 관리자를 열고 성능 탭으로 이동하여 OS에서 실행중인 스레드 수를 확인하십시오. 지금 832 명이 있습니다. 그래서 나는 하나의 mroe가 그렇게 나쁘지 않을 것이라고 생각한다 : D –
그리고 이것은 하나의 쓰레드에서 수행 될 수있다 : 만일 당신이 큐에 핸들을 추가하고 5000을 기다리지 않는다면, 실행해야 할 X 개 이상의 핸들이 있다면 모두 실행하고 5000 –