2013-08-09 3 views
0

В приведенном ниже коде показан таймер, который отметит каждые 100 * 1000 (миллисекунды), чтобы отобразить всплывающее сообщение для регистрации. Нижеприведенный код работает, но, к сожалению, мое приложение зависает через некоторое время.System.Timers.Timer зависает приложение Windows Forms в C#

Я искал в google и stackoverflow для этого ответа. Но я не смог найти правильный ответ, чтобы заставить мое приложение работать, не повесившись.

 private System.Timers.Timer register_Timer = new System.Timers.Timer(); 

     register_Timer.Interval = (100 * 1000); 
     register_Timer.Elapsed += new ElapsedEventHandler(register_Timer_Tick);  
     register_Timer.SynchronizingObject = this;    
     register_Timer.AutoReset = true;  
     register_Timer.Enabled = true; 

     System.GC.KeepAlive(register_Timer); 

     private void register_Timer_Tick(object sender, EventArgs e) 
       { 
       //Pop up to show register message 
       } 
+0

1) Что GC.KeepAlive ничего не делает, вы видите http://stackoverflow.com/q/18136735/56778. 2) На самом деле нет необходимости делать математику за интервал. 'TimeSpan.FromSeconds (100) .TotalMilliseconds' более ясен. Не большое дело, когда вы просто делаете 100 секунд, но если вы хотите 27 минут или 3 часа и 12 минут, использование 'TimeSpan' намного более понятно. –

+0

Я думаю, что ваше приложение подвешено по другой причине. Этот код работает нормально для меня. Я думаю, что это очень похоже на «System.Windows.Forms.Timer». Если у вас нет кода в другом месте, который может вызвать эту проблему. –

+0

Какой вид вы показываете? –

ответ

5
register_Timer.SynchronizingObject = this; 

Это полностью опровергает причину использования System.Timers.Timer. Это препятствует тому, чтобы обработчик события Elapsed был поднят в потоке threadpool, свойство гарантирует, что он будет работать в потоке пользовательского интерфейса. Это то, что вы хотели.

Но у вас все еще есть все недостатки этого класса Timer. В частности, его привычка к глотанию исключений без диагностики очень уродлива. Так же как и продолжая поднимать Истекшее событие после того, как форма закрыта, гарантировать это не может, это очень трудная проблема для решения, есть два присущих условиям гонки. У .NET 1.0 были некоторые ошибки проектирования, связанные с потокованием, это был один из них.

Просто не делайте этого, используйте вместо этого System.Windows.Forms.Timer. Он будет работать точно так же, как ваш таймер, минус все недостатки.

+0

Благодарим вас за ответ. Но я также попробовал использовать «System.Windows.Forms.Timer» до того момента, пока приложение не повесится. :( – Mothy

+1

Использование System.Timers.Timer не может исправить исходную проблему в вашем коде. Разумеется, более разумно задавать вопрос * этого вопроса. По крайней мере, каждый может устранить проблему с потоками, поскольку любая проблема влияет на вашу программу. кнопку Ask Question и не забудьте опубликовать фрагмент, который воспроизводит зависание, на этот раз с использованием синхронного таймера. –

1

Приложение зависает, потому что вы делаете всплывающее окно (я предполагаю, что MessageBox или какое-то другое модальное диалоговое окно). Конечно, приложение будет висеть. Вы вставляете модальный диалог в поток пользовательского интерфейса.

Проблема не в таймере, а в дизайне вашего приложения.

+0

Да, я использую сообщение. Можете ли вы рассказать мне, как я могу заставить приложение работать без зависания? – Mothy

+0

@Mothy : Чтобы устранить проблему, вам нужно использовать другой способ для получения уведомления. Вам нужно немодальное диалоговое окно или написать информацию в текстовое поле или что-то подобное в основной форме. –