2012-06-25 3 views
0

У меня есть задача, которая периодически проходит 10 секунд. Я делаю некоторые обновления освежающих процессов, читая базу данных. Я хочу, чтобы вызывать или пробуждать поток и выполнять операцию обновления, когда я нажимаю кнопку на кнопку. Короче говоря, я хочу, чтобы задача обновления управлялась не только временем, но и событием вместе. Это возможно? Если да, то как? Кодовый блок для задачи показан ниже.Пробуждение задания во время сна

while (true) 
{ 
    // do some refresh operation 
    Thread.Sleep(10000); 
} 

void button1_Click(object sender, EventArgs e) 
{ 
    // invoke or awaken thread 
} 
+0

не с этим время цикла - в основном с Thread.Sleep вы говорите Windows - не планируйте этот поток в течение следующих 10 секунд. Я не знаю, как это получить. Вы можете уменьшить временной интервал и проверить переменную внутри цикла. – Bond

+0

Используйте таймер! он построен для этого. Вы даже избегаете выполнения многопоточных операций, поскольку событие тика будет запущено в потоке пользовательского интерфейса. –

+0

Что я не понимаю, так это: предположим, что таймер обновил графический интерфейс, а затем через 5 секунд вы нажмете кнопку для другого обновления вручную. Если таймер запускает собственное обновление через 5 секунд или останавливается до следующего хода? – Tudor

ответ

4

Во-первых, я бы посоветовал вам бросить комбо Thread + Sleep + Invoke для синхронизированных по времени операций. Это очень уродливо. Существуют классы таймера как для WinForms, так и для WPF, чтобы делать эти три вещи автоматически (периодически обновлять графический интерфейс из потока диспетчера). Проверьте System.Windows.Forms.Timer и System.Windows.Threading.DispatcherTimer.

Теперь для вашего конкретного вопроса вы можете просто определить общий способ обновления GUI с тем, что вам нужно, и назвать его как из кода таймера, так и из обработчика кнопок.

0

Создать AutoResetEvent:

protected AutoResetEvent _threadCycle; 
_threadCycle = new AutoResetEvent(false); 

когда вы хотите ждать сделать:

_threadCycle.WaitOne(delay, false); 

и когда вы хотите установить событие, действенно позволяя нить продолжать:

_threadCycle.Set(); 

BONUS:

, когда вы сделаете _threadCycle.WaitOne(delay, false);, вы получите возвращаемое значение, true или false, которое вы можете проверить, чтобы узнать, истекает ли тайм-аут или вы продолжаете из-за события, установленного вручную.

КСТАТИ:

, который будет работать только если вы делаете свою задачу в другом потоке. Если вы используете основной поток, вы все равно задержитесь в ожидании завершения таймаута. Может быть, лучше всего использовать ответ @Tudors и получить этот вариант только как «через шипы».

0

Для этого вам следует использовать AutoResetEvent.

Что вы делаете, что-то вроде (предполагается, что ваш AutoResetEvent называется «сигнал»):

while (true) 
{ 
    signal.WaitOne(10000); 
    ... 
} 

И в обработчике кнопки, просто сделать:

signal.Set(); 
Смежные вопросы