2013-02-17 2 views
2

В моем проекте я создал объект System.Timers.Timer и интервал установлен в 10 мин. На каждые 10 минут я получаю истекшее событие. В этом обработчике событий я выполняю некоторый код.System.Timers.Timer enabled and GarbageCollector

Перед выполнением этого кода я устанавливаю значение Enabled, равное false, потому что если обработчик занимает больше времени, чем следующий интервал, другой поток выполняет истекшее событие.

Проблема здесь внезапно Elapsed мероприятие остановлено.

Я прочитал несколько статей и заподозрил, что момент, когда свойство свойства установлено в false garbagecollector, освобождает объект таймера.

Если это правильно, сообщите мне решение.

Ниже приведен пример кода:

public class Timer1 
{ 
    private static System.Timers.Timer aTimer; 

    public static void Main() 
    { 
     // Create a timer with a ten second interval. 
     aTimer = new System.Timers.Timer(10000); 

     // Hook up the Elapsed event for the timer. 
     aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 

     // Set the Interval to 10min. 
     aTimer.Interval = 600000; 
     aTimer.Enabled = true; 

     Console.WriteLine("Press the Enter key to exit the program."); 
     Console.ReadLine(); 
    } 

    private static void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     aTimer.Enabled = false; 

     // excutes some code 

     aTimer.Enabled = true; 
    } 
} 
+1

Какая ссылка для этой статьи? Это звучит неправильно для меня. Какая причина, по которой GC собирает все еще ссылающийся объект с свойством, установленным на какое-то значение? Это очень необычное поведение GC в .NET. – abatishchev

+0

Спасибо за ваш ответ. . Посмотрите на приведенные ниже журналы, в которых указано, что «когда свойство Enabled установило его на false, оно было отмечено для GC, чтобы он мог освобождать ресурсы, удерживаемые таймером». http://forums.codeguru.com/printthread. PHP? т = 342524 http://kvarnhammar.blogspot.com/2008/12/systemwindowsformstimer-and-garbage.html http://stackoverflow.com/questions/14617336/garbage-collection-and-gchandle- alloc http://stackoverflow.com/questions/14216098/why-does-a-timer-keep-my-object-alive – user2080185

ответ

3

Поскольку у вас есть поле в своем классе, указывающей на ваш объект таймера, ГХ не будет собирать объект таймера.

Но ваш код может вызвать исключение, и это может привести к тому, что свойство Enabled станет истинным. Для защиты agianst это, вы должны использовать finally блок:

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    aTimer.Enabled = false; 
    try 
    { 
     // excutes some code 
    } 
    catch(Exception ex) 
    { 
     // log the exception and possibly rethrow it 
     // Attention: never swallow exceptions! 
    } 
    finally 
    { 
     aTimer.Enabled = true; 
    } 
} 
+0

Спасибо за ваши ответы, я попробую, как вы сказали. . Посмотрите на приведенные ниже журналы, в которых указано, что «когда свойство Enabled установило его на false, оно было отмечено для GC, чтобы он мог освобождать ресурсы, удерживаемые таймером». http://forums.codeguru.com/printthread. PHP? т = 342524 http://kvarnhammar.blogspot.com/2008/12/systemwindowsformstimer-and-garbage.html http://stackoverflow.com/questions/14617336/garbage-collection-and-gchandle- alloc http://stackoverflow.com/questions/14216098/why-does-a-timer-keep-my-object-alive – user2080185

+0

@ user2080185 Эти ссылки все говорят об объектах таймера, которые ** выходят из scopt ** но ** не сбор мусора **. Но ваша ситуация обратная. Ваш таймер ** находится в области **, и вы держите референс к нему. Поэтому GC никогда не собирает его, пока вы ** не остановите таймер ** и ** не отдадите ссылку ** на объект таймера. Случаи в этой должности не относятся к вашей ситуации. –

0

Вы можете установить объект синхронизации, в этом случае истекшего будет происходить только на владельца резьбе этого объекта, без параллелизма. Аналогичный вопрос размещен здесь: Do C# Timers elapse on a separate thread?

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