2016-11-16 4 views
-4

Я работаю над проектом, который должен блокировать текущую нить для промежутка времени, который может варьироваться от одной секунды до нескольких месяцев.Блокировка потока дольше, чем Int32.MaxValue

Подход, с которым я пришел, заключался в использовании метода EventWaitHandle.WaitOne (или любого из его братьев и сестер) с указанным таймаутом. Проблема в том, что все эти методы принимают Int32 в качестве параметра, который перекрывает максимальное время блока примерно до 25 дней.

Кто-нибудь знает об этом? Как заблокировать поток дольше, чем миллисекунды Int32.MaxValue?

благодаря

UPDATE

Просто для записи, вот фрагмент кода я наконец придумал:

while(_doRun) 
{ 
    // Determine the next trigger time 
    var nextOccurence = DetermineNextOccurence(); 
    var sleepSpan = nextOccurence - DateTime.Now; 

    // if the next occurence is more than Int32.MaxValue millisecs away, 
    // loop to work around the limitations of EventWaitHandle.WaitOne() 
    if (sleepSpan.TotalMilliseconds > Int32.MaxValue) 
    { 
    var idleTime = GetReasonableIdleWaitTimeSpan(); 
    var iterationCount = Math.Truncate(sleepSpan.TotalMilliseconds/idleTime.TotalMilliseconds); 
    for (var i = 0; i < iterationCount; i++) 
    { 
     // Wait for the idle timespan (or until a Set() is called). 
     if(_ewh.WaitOne(idleTime)) { break; } 
    } 
    } 
    else 
    { 
    // if the next occurence is in the past, trigger right away 
    if (sleepSpan.TotalMilliseconds < 0) { sleepSpan = TimeSpan.FromMilliseconds(25); } 

    // Wait for the sleep span (or until a Set() is called). 
    if (!_ewh.WaitOne(sleepSpan)) 
    { 
     // raise the trigger event 
     RaiseTriggerEvent(); 
    } 
    } 
} 

Этот сниппет код выполняется с помощью специальной нити. Обратите внимание, что EventWaitHandle.Set() вызывается только тогда, когда приложение завершает работу или отказывается отменить планировщик.

Спасибо тем, кто хочет помочь.

+0

Вы действительно думаете, что ваше приложение может работать так долго? Это наверняка потерпит крах на 23-й день во время тестирования. –

+11

Звучит для меня как-то ужасно неправильно с дизайном. – eurotrash

+0

Вы должны начать свою тему на каком-то мероприятии. Или используйте таймер, который не будет потрачен впустую, чтобы принять поток. –

ответ

0

Пробег: handle.WaitOne(System.Threading.Timeout.Infinite).

Если вы не хотите, чтобы он работал бесконечно, выведите ручку ожидания извне из другой нити.

UPDATE:

Если вы не хотите использовать другую нить, используйте цикл:

bool isTriggered = false; 
while (!isTriggered) { 
    isTriggered = handle.WaitOne(timeout); 
    //Check if time is expired and if yes, break 
} 

Вы должны разделить ваш тайм-аут отрезок времени на несколько кусков, которые вписываются в Int32 , Переменная isTriggered покажет вам, был ли запущен ручка или если он был отключен.

+2

вы не можете быть уверены, что это был вопросник, который отклонил ваш ответ. – stuartd

+0

Достаточно честный. Что касается этой темы, я не знаю. – Sefe

+0

@Sefe Я не проголосовал (недостаточно очков репутации). Но для работы, о котором вы предлагаете, потребуется другой поток, чтобы узнать о прохождении времени. – JuiceOntour