How can a one-off System.Threading.Timer be used?

I would like to use System.Threading.Timer

to execute once. This timer should be deterministically cleared by calling Dispose

it as soon as it is no longer needed (that is, when the callback fires).

The problem is that the callback cannot reliably get a reference to Timer

!

System.Threading.Timer timer = null;
timer = new System.Threading.Timer(_ =>
{
    Console.WriteLine("Elapsed.");

    //Dispose the timer here, but timer might be null!
    timer.Dispose(); //BUG
}, null, TimeSpan.FromSeconds(1), TimeSpan.Zero);

      

The variable Timer

may not be initialized when the callback fires. This code does not work in all cases because it contains a race condition.

How can we use System.Threading.Timer

to create a one shot timer with deterministic clear?

(More efficient ways to create a one-shot timer / delay are beyond the scope of this question. I am deliberately asking this in a certain way.)

+3


source to share


1 answer


Go to the timer constructor that only gets the callback so that it goes by itself in the state parameter, Use Change()

to set it up right after:

        System.Threading.Timer timer = null;
        timer = new System.Threading.Timer((state) =>
        {
            Console.WriteLine("Elapsed.");

            // Dispose of the timer here:
            ((System.Threading.Timer)state).Dispose();
        });
        timer.Change(TimeSpan.FromSeconds(1), TimeSpan.Zero);

      



If you don't like using a parameter state

, you can also use a closure variable, as the code in the question does. The key does not start the timer using the constructor. Run it only after the timer link has been saved.

+5


source







All Articles