2014-11-14 3 views
2

Может ли таймер остановить поток, который теперь работает, возвращаясь из обратного вызова?System.Threading.Timer останавливает поток?

Мне нужен таймер, который запустит некоторую функцию за определенное время. Но эта функция длится больше, чем таймер.

_timer = new System.Threading.Timer(new TimerCallback(Process), null, TimeSpan.Zero, TimeSpan.FromHours(1)); 

и обратного вызова:

public void Process(Object stateinfo) 
{ 
    DateTime dt = DateTime.Now.ToUniversalTime(); 
    //run once a day between 2 and 5 am 
    if (LastCheckDateTime == DateTime.Today || dt.ToString("HHmm").CompareTo("0200") < 0 || dt.ToString("HHmm").CompareTo("0500") > 0) 
    return; 

    try 
    { 
     LastCheckDateTime = DateTime.Today; 
     foo(); //lasts 4 hours 
    } 
    catch (Exception ex) 
    { 
     LastCheckDateTime = DateTime.MinValue; 
     //if some problems, Process must start again until 5 am 
    } 
} 

Этот код начался сегодня в 2:56 утра, но не закончил, Это потому, что в 5 часов утра он все еще работает?

И как это исправить?

+0

Вы хотите прервать операцию, если длится более тик таймера? –

+0

Нет, это нормально, я просто хочу, чтобы он начинался с 2 и перезапускался до 5, если что-то не так. – tammaco

+0

Что вы подразумеваете под * "до 5" *? если требуется более 3 часов, перезапустите его? –

ответ

2

Ваш код работает, вы использовали лучший таймер в своем уме (System.Threading). Невозможно повторно выполнить тот же метод, даже если предыдущий вызов еще не завершен. Предыдущий экземпляр не убит. Вам просто нужно управлять повторной установкой, но так, как вы это делали, это предотвращает проблемы (ваш таймер срабатывает каждый час, поэтому между строкой, которая проверяет «LastCheckDateTime» и строку, изменяющую ее значение, нет проблемы с потоками).

Я пробовал следующее, которое хорошо работает: событие запускается каждую секунду, но «Процесс» начинается с ожидания 3 секунд.

public partial class MainWindow : Window 
{ 
    private System.Threading.Timer _timer; 

    public MainWindow() 
    {    
     InitializeComponent(); 
     _timer = new Timer(new System.Threading.TimerCallback(Process), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); 
    } 

    private void Process(object state) 
    { 
     DateTime dt = DateTime.Now; 
     System.Threading.Thread.Sleep(3000); 
     Debug.WriteLine("dt=" + dt.ToString("HH:mm:ss.fff") + " Now=" + DateTime.Now.ToString("HH:mm:ss.fff")); 

    } 

} 

С наилучшими пожеланиями,

+0

Большое спасибо за ответ, я просто хочу подняться, если эта хорошая практика для использования сна? В программе есть еще один поток, который также использует Sleeps, но они реализованы через Thread: new Thread (новый ThreadStart (this.Process)); – tammaco

+0

, и я до сих пор не понимаю, почему foo() остановился без исключения, что может помешать этому? Таймер не мог этого сделать? – tammaco

+0

Действительно, вы правы, Thread.Sleep() не является хорошей практикой вообще. Но это действительно полезно для меня в тестовых целях. Для «реального кода» это всегда возможно, чтобы обрабатывать задержки с помощью таймеров или асинхронного кода (BackgroundWorker, events, IAsyncResult, Task <>). – Elo

Смежные вопросы