Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to call a single operation at some time in the future?

Tags:

c#

.net

lambda

I want to fire off a timer to execute once at some point in the future. I want to use a lambda expression for code brevity. So I want to do something like...

(new System.Threading.Timer(() => { DoSomething(); },
                    null,  // no state required
                    TimeSpan.FromSeconds(x), // Do it in x seconds
                    TimeSpan.FromMilliseconds(-1)); // don't repeat

I think it's pretty tidy. But in this case, the Timer object is not disposed. What is the best way to fix this? Or, should I be doing a totally different approach here?

like image 356
noctonura Avatar asked Oct 20 '25 05:10

noctonura


2 Answers

That approach is flawed.
You are creating an object in memory with no reference to it. This means that the timer object is available to be garbage collected. While this code will work some of the time, you cannot predict when a garbage collection will kick in and remove the timer.

For example in the code below I force a garbage collection and it causes the timer to never fire.

static void Main(string[] args)
{
    DoThing();
    GC.Collect();
    Thread.Sleep(5000);
}


static void DoThing()
{
    new System.Threading.Timer(x => { Console.WriteLine("Here"); },
            null,  
            TimeSpan.FromSeconds(1), 
            TimeSpan.FromMilliseconds(-1));
}
like image 97
Matthew Manela Avatar answered Oct 21 '25 20:10

Matthew Manela


This will accomplish what you want, but I am not sure its the best solution. I think its something that short and elegant, but might be more confusing and difficult to follow than its worth.

System.Threading.Timer timer = null;
timer = new System.Threading.Timer(
    (object state) => { DoSomething(); timer.Dispose(); }
    , null // no state required
    ,TimeSpan.FromSeconds(x) // Do it in x seconds
    ,TimeSpan.FromMilliseconds(-1)); // don't repeat
like image 38
chrisghardwick Avatar answered Oct 21 '25 18:10

chrisghardwick