2013-07-03 2 views
0

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

Это мои пользовательские события

public void OnInactive(EventArgs e) 
{ 
    this.OnInactive(new EventArgs()); 
    do 
    { 
     var idle2 = GetIdleTime(); 
     GetIdleTime(); 
     System.Diagnostics.Debug.WriteLine(idle2); 
    } 
    while (timer.Interval > 5000); 
} 

public void OnActive(EventArgs e) 
{ 
    this.OnActive(new EventArgs()); 
    if (timer.Interval < 5000) 
    { 
     var idle3 = GetIdleTime(); 
     System.Diagnostics.Debug.WriteLine(idle3); 
    } 
} 

Я breakpointed код, чтобы попытаться найти источник проблемы, которая, как представляется, лежат в пределах this.OnInactive(new EventArgs());, однако я довольно озадачен о том, как решить эту проблему вопрос, поскольку я новичок в пользовательских событиях и долгое время не кодировал в C#.

Любая помощь с этой проблемой была бы принята с благодарностью!

Заранее спасибо =]

+0

Прежде всего удалите все точки останова и работайте с файлом журнала. вы можете поместить следующие строки, чтобы добавить файл журнала File.AppendAllText (путь, «MessageValueOrVariableValue») –

+0

Это немного расплывчато, все, что я пытаюсь сделать, это запустить это событие. –

ответ

5

Обработчик метод немедленно называющая себя на входе:

this.OnInactive(new EventArgs()); 

это приводит к последовательности вызовов:

OnInactive -> OnInactive -> OnInactive - > ... ->

, который будет продолжаться до тех пор, пока вы не закончите пространство стека, а StackOverflowException будет выведено во время выполнения.

Непонятно, что вы пытаетесь достичь с помощью рекурсивного вызова, но вы должны просто удалить его.

У вас такая же проблема в вашем обработчике OnActive.

EDIT: В ответ на комментарии кажется, что вы пытаетесь поднять это событие в начале вашего метода. Если предположить, что объявление событий выглядит следующим образом:

public event EventHandler InActive; 

, то вы можете поднять его с:

EventHandler inactiveEvent = this.InActive; 
if(inactiveEvent != null) 
{ 
    inactiveEvent(this, e); 
} 

и аналогично для вашего Active события.

+0

Спасибо за ответ Супер-быстро Ли, однако я Я уже пробовал это решение, и событие, похоже, вообще не срабатывает, когда я прокомментирую эти строки кода и из того, что я понимаю, исследуя в Интернете. Мне нужен этот вызов для запуска события. –

+0

Возможно, он имел в виду ' base.onInactive() ' – haim770

+0

@ReeceCottam - обработчик должен быть вызван один раз, иначе вы никогда не получите переполнение стека. Как вы регистрируете дескриптор события? У ваших обработчиков OnInactive и OnActive нет ожидаемой сигнатуры для обработчиков событий. – Lee

0

Я предполагаю, что вы пытаетесь вызвать базовый метод, но на самом деле вы сейчас вызываете OnInactive при ударе OnInactive. Это поведение является рекурсивным и окончательно прекратится из-за StackOverflow exception.

Вы можете вызвать базовую функцию с помощью base.<function name>. Например:

class SpecialDerived : Base 
{ 
    public override void Say() 
    { 
     Console.WriteLine("Called from Special Derived."); 
     base.Say(); 
    } 
} 

Подробнее: http://msdn.microsoft.com/en-us/library/hfw7t1ce(v=vs.71).aspx

+0

Нет, я пытаюсь запустить это событие, которое, похоже, не работает в данный момент –

0

это не обработчики событий, это методы, которые собираются назвать, чтобы поднять активные и неактивные события - Reece Cottam

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

public class ReecesWatcher 
{ 
    public event EventHandler ActiveEvent; 
    public event EventHandler InactiveEvent; 


    protected virtual void OnInactive(EventArgs e) 
    { 
     // Fire the event using the() syntax. Fire it through 
     // a test variable so that we can reliabilty test for null, 
     // if there are no subscribers. 
     EventHandler inactiveEventTest = InactiveEvent; 
     if (inactiveEventTest != null) 
     { 
      inactiveEventTest(this, new EventArgs()); 
     } 

     do 
     { 
      var idle2 = GetIdleTime(); 
      GetIdleTime(); 
      System.Diagnostics.Debug.WriteLine(idle2); 
     } 
     while (timer.Interval > 5000); 
    } 

    protected virtual void OnActive(EventArgs e) 
    { 
     // Fire the event using the() syntax. Fire it through 
     // a test variable so that we can reliabilty test for null, 
     // if there are no subscribers. 
     EventHandler activeEventTest = ActiveEvent; 
     if (activeEventTest != null) 
     { 
      activeEventTest(this, new EventArgs()); 
     } 

     if (timer.Interval < 5000) 
     { 
      var idle3 = GetIdleTime(); 
      System.Diagnostics.Debug.WriteLine(idle3); 
     } 
    } 

    // ... the rest of your class, where you call OnActive and OnInactive to 
    // cause the events to be fired. 
} 

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

+0

Важное изменение! Я оставил ключевое слово «virtual» для защищенных методов. – antiduh

0

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

Class A{ 
    public event OnInactive; 
    public event OnActive; 
} 

, если в классе А произошли какие-либо изменения, которые вы хотите обновить в ClassB. Таким образом, вы будете реализовывать события класса A в ClassB.

this ссылка будет вам описать подробно.

Мое понимание гласит, что нет событий, когда вы запускаете его из одного класса и слушаете в одном классе.

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