2009-11-11 3 views
28

Я не смог найти ответ на этот вопрос в любом месте ...исключения Бросив в методе обратного вызова для Таймеры

Что происходит с исключениями выброшенных в методе обратного вызова для System.Threading.Timer, (или в случае обработчик для System.Timers.Timer). Является ли исключение распространенным в потоке, на котором был создан таймер, или это исключение исключено?

Каковы побочные эффекты бросания исключения в функции обратного вызова таймера?

Что было бы правильным способом сигнализировать потоку создания таймера, что было выбрано исключение в рабочем потоке (метод обратного вызова)?

Спасибо за ваше время.

ответ

32

Исключение не передается обратно вызывающему потоку. Если вы хотите, чтобы это было, вы можете добавить блок catch и выяснить способ сигнала для вызывающего потока. Если вызывающий поток представляет собой поток WinForms или WPF UI, вы можете использовать класс SynchronizationContext для передачи вызова в поток пользовательского интерфейса. В противном случае вы можете использовать потокобезопасную очередь (или блокировку синхронизации) и периодически проверять ее в другом потоке.

System.Timers.Timer беззвучно проглотит исключения и продолжит таймер (хотя это может быть изменено в будущих версиях фреймворка); System.Threading.Timer прекратит выполнение программы.

+1

Хороший материал, спасибо за информацию. – thismat

+1

+1 для консультации по использованию таймера. Я искал причину, по которой мое InvalidCastException вызывает повреждение моего приложения вместо того, чтобы перехватывать исключение. – IAbstract

+0

Таким образом, мы не можем справиться с ними иначе, чем выполнять целую вызванную функцию внутри блока catch try при использовании System.Threading.Timer? – MonsterMMORPG

1

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

Необработанные исключения в потоке (System.Threading.Timer) остановят всю вашу программу.

0

Я не знаю, если это лучшее решение, но то, что я сделал, было небольшим обходным решением. Мой вызывающий поток подписался на событие для исключения исключений из потоков. Поэтому, когда в каком-то потоке возникает исключение, скажем, в событии TimerElapsed, затем формируйте блок catch, который я вызываю в качестве аргумента событию объект исключения события.

EventHolderCallingClass: Он должен определить делегат и событие, как показано ниже.

public class EventHolderCallingClass 
{  
    public delegate void HandleExceptionEventDelegate(Exception exception); 
    public event HandleExceptionEventDelegate HandleExceptionEvent ; 

    void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
    try 
    { 
     //some operation which caused exception. 
    } 
    catch(Exception exception) 
    { 
     if(HandleExceptionEvent!=null) 
     HandleExceptionEvent(exception) 
    } 
    } 
} 

Event Handler Class (Exception Handler):

public EventHandlerClassConstructor() 
    { 
      EventHolderCallingClass.HandleExceptionEvent += new EventHolderCallingClass.HandleExceptionEventDelegate(HandleExceptionEventHandler);    
    } 

    void HandleExceptionEventHandler(Exception exception) 
    { 
     //handle exception here. 
    } 
Смежные вопросы