CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Apr 2011
    Posts
    58

    Multiple timers calling the same EventHandler... which one called it?

    I have some timers stored in a Dictionary<string, Timer>. I could change that and store them differently if need be. The timers all call the same EventHandler to do things like remove objects from other dictionaries. But how can I tell which timer has elapsed and fired the EventHandler?
    Code:
    Dictionary<string, System.Timers.Timer> currentAlertsTimers = new Dictionary<string, System.Timers.Timer>();
    
    currentTimersList[currentKey].Elapsed += new ElapsedEventHandler(AlertHasExpired);
    currentTimersList[currentKey].Interval = waitTime.TotalMilliseconds;
    currentTimersList[currentKey].Enabled = true;
    
    public void AlertHasExpired(object source, ElapsedEventArgs e)
    {
      //delete the objects in the other dictionaries that have the same key and the timer that elapsed and fired this EventHandler
    }

  2. #2
    Join Date
    May 2011
    Posts
    18

    Re: Multiple timers calling the same EventHandler... which one called it?

    Make sure you have this using statement...
    using System.Linq;

    You in your AlertHasExpired routine, do this....

    var firedtimer = (from tmpTimer in currentTimerList
    where tmpTimer.Value.Equals(sender)
    select tmpTimer).FirstOrDefault();


    currentTimerList.Remove(firedtimer.Key);

  3. #3
    Join Date
    Apr 2011
    Posts
    58

    Re: Multiple timers calling the same EventHandler... which one called it?

    I don't really understand yet how this works. The part inside the parenthesis look a lot like a SQL statement. What do you call this type of function/method? I want to read up on it, and searching for the words from, where, and select can be tricky.
    By the way, I have not been able to get this running yet. I'm not sure what the reference to (sender) really meant and what I was supposed to put there. Simply putting "sender" there obviously won't work (at least ti didn't for me).

    Thanks for replying though. I think I am headed in the right direction.

    Skip

  4. #4
    Join Date
    May 2011
    Posts
    18

    Post Re: Multiple timers calling the same EventHandler... which one called it?

    this piece of code below is utilizing LINQ. Similar to SQL in its Syntax, it allows you to query objects that are Enumerable (meaning you can loop through them...i.e. your dictionary).

    So you place this piece of code inside your "AlertHasExpired" method.


    Code:
    var firedtimer = (from tmpTimer in currentTimerList
    where tmpTimer.Value.Equals(sender)
    select tmpTimer).FirstOrDefault();
    So, the way it works is like this. A timer will elapse and fire the Elasped Event which in turn calls the "AlertHasExpired" method. That method contains 2 params... an sender/source param and an EventArgs param. The sender/source object will be the timer that elapsed, which is what you want.

    Now, you have to identify that timer so you can remove it from your dictionary. That is where the LINQ statement comes in.

    The "var firedtimer" will hold the timer we are looking for.
    The "from tmpTimer in currentTimerList" means we are taking the contents of "currentTimerList" and putting them in a temporary variable "tmpTimer" for the purpose of Querying that List/Dictionary.
    The "where tmpTimer.Value.Equals(sender) "is where we tell LINQ to look for the timer(s) in our dictionary that match our "Sender".
    The "select tmpTimer" is telling LINQ to select the timers our of your list/dictionary that match your where clause....
    The ".FirstOfDefault()" was added because without it, var firedTimer would be a dictionary. It would contain a Dictionary of either 0 elements, 1 elements or multiple elements. So, the "FirstOrDefault" will return either thr first Value/Key pair in the Dictionary OR if we don't have a match it will return an Empty Dictionary. Linq has a "First()" method but, if the query where to not return any results, we would error out and we don't want that.

    So by the end of that statement, var firedTimer should contain the value/keypair of the timer that fired the event.

    If you have multiple dictionaries that you perform this on, then you just need to repeat that LINQ statement and replace "currentTimerList" with the name of whatever list/dictionary you are using.

    Now, to utilize it, you must be using VS 2008. If you are using VS 2005, then you are going to have to replace that code block with a foreach loop and then compare the current item in your loop with the contents of the "Sender".

    Now, i guess i should have used "Source" instead of "Sender". When I was testing this on my machine, my object name was Sender instead of Source. See your method as a reference

    Code:
    public void AlertHasExpired(object source, ElapsedEventArgs e)
    {
      //delete the objects in the other dictionaries that have the same key and the timer that elapsed and fired this EventHandler
    }
    Now from the above code snippet, the "object source" it the object that fired this event. So, if in your dictionary, you have 10 timers that all point to this event handler, then eventually, all timers will come here. then the "Source" is an object of the type "System.Timers.Timer".

  5. #5
    Join Date
    Apr 2011
    Posts
    58

    Re: Multiple timers calling the same EventHandler... which one called it?

    It works! Awesome. Thanks for the very detailed explanation. For a guy/gal with only 4 posts (and two of them for me), I hope you will stick around here and help out some more

    I'm going to read up on the LINQ class. Thanks again.

    Skip

  6. #6
    Join Date
    Oct 2015
    Posts
    1

    Re: Multiple timers calling the same EventHandler... which one called it?

    Hi all,
    I am trying to use this in my code, but it is not working for me The "var firedtimer" is null at the end .... can you help me?
    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
    Dictionary<string, Tuple<int, int, System.Timers.Timer>> dictionary_copy = dictionary.ToDictionary(entry => entry.Key, entry => entry.Value);

    Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}", e.SignalTime);

    var firedtimer = (from tmpTimer in dictionary_copy
    where tmpTimer.Value.Item3.Equals(source)
    select tmpTimer).FirstOrDefault();

    dictionary.Remove(firedtimer.Key);
    }

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Multiple timers calling the same EventHandler... which one called it?

    Your code is different. Yours contains .Value.Item3. Where did that come from?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured