crush
crush

Reputation: 17023

How to reschedule C# System.Threading.Timer?

I'm attempting to create a Session implementation. In order to complete it, I need to create Session timeouts. To do this, I decided I should use a Timer that executes after x seconds. However, if a request is received before that timer expires, then it should be rescheduled.

So, I have a timer:

using System.Threading.Timer;

public class SessionManager {
    private int timeToLive; //Initialized in the constructor.
    private ConcurrentDictionary<Guid, Session> sessions; //Populated in establishSession. Removed in abandonSession.

    public Session establishSession(...)
    {
        Session session = ...; //I have a session object here. It's been added to the dictionary.

        TimerCallback tcb = abandonSession;
        Timer sessionTimer = new Timer(tcb, null, timeToLive, Timeout.Infinite);
    }

    public void abandonSession(Object stateInfo)
    {
        //I need to cancel the session here, which means I need to retrieve the Session, but how?
    }

    public void refreshSession(Session session)
    {
        //A request has come in; I have the session object, now I need to reschedule its timer. How can I get reference to the timer? How can I reschedule it?
    }
}

What I need help with:

  1. I could make the sessionTimer a member of the Session object. That would give me access to the Timer object in refreshSession() but I don't know how to "reschedule" it.

  2. I still don't have any idea how I can get a reference to the Session in abandonSession() callback. Is there a way to send the Session object in the stateInfo?

I was thinking I could store a reference to the SessionManager on the Session object, and have the callback reference a method on the Session object for the abandonSession() call. That seemed sloppy though. What do you think?

Please, let me know if additional information is needed.

Upvotes: 1

Views: 785

Answers (1)

Haney
Haney

Reputation: 34852

Use the Change method to set a new invocation delay:

sessionTimer.Change(timeToLive, timeToLive)

As for getting a value in your callback method, the second parameter that you currently pass as null is your callback object... Your Timer callback method forces a signature of object and you can cast that object to your passed in type to use it.

var myState = new Something();
var sessionTimer = new Timer(tcb, myState, timeToLive, Timeout.Infinite);

...

public void abandonSession(Object stateInfo)
{
    var myState = (Something)stateInfo;
    //I need to cancel the session here, which means I need to retrieve the Session, but how?
}

Upvotes: 1

Related Questions