What is the easiest way to have a temporary callback in .NET?

I want to do something like this in C # (more precisely, WPF):

Thread.Invoke(MyCallback, 1000); 

Which will just call MyCallback, 1 time, 1 second.

What is the easiest way to do this with .NET? Should I set a timer and hook an event?

+4
source share
6 answers

You can use System.Timers.Timer to not create your own stream. Make an Elapsed callback to do what you want by setting Enabled true and AutoReset false to achieve one call.

Make sure you Dispose the Timer object when you are done with it!

+6
source

Here we use the Action method after a certain timeout using Timer :

 static void Invoke(TimeSpan dueTime, Action action) { Timer timer = null; timer = new Timer(_ => { timer.Dispose(); action(); }); timer.Change(dueTime, TimeSpan.FromMilliseconds(-1)); } 

I'm not sure how easy the timer is in accuracy, but it should be better than blocking the ThreadPool thread.

Using:

 Invoke(TimeSpan.FromSeconds(5), () => { Console.WriteLine("Hello World"); }); 
+3
source
 Task.Factory.StartNew(() => { Thread.Sleep(1000); // Do Stuff }); 

As noted in the comments below, although this is easy to understand and write briefly, it is a relatively inefficient / resource hungry way to do this.

+2
source

Using:

 Delay.Invocation(MyCallback, 1000); //or Delay.Invocation(() => MyCallbackWithArgs(arg1, arg2), 1000); 

Packing:

 public class Delay { readonly Timer _timer; readonly Action _action; private Delay(Action action, double delayMilliseconds) { _action = action; _timer = new Timer(delayMilliseconds); _timer.Elapsed += ExecuteCallback; } void ExecuteCallback(object sender, ElapsedEventArgs e) { _timer.Stop(); _timer.Elapsed -= ExecuteCallback; _timer.Dispose(); _action(); } void Begin() { _timer.Start(); } public static void Invocation(Action action, int delayMilliseconds) { var delay = new Delay(action, delayMilliseconds); delay.Begin(); } } 
0
source

Only my 2 cents

 public class WaitableWorker { private readonly System.Threading.Timer timer; public WaitableWorker(int interval, Action callback, bool blocking = false) { if (blocking) { Thread.Sleep(interval); callback(); } else { timer = new System.Threading.Timer(_ => { timer.Dispose(); callback(); }, null, interval, Timeout.Infinite); } } } 

Using

  WaitableWorker worker=new WaitableWorker(3000,DoWork); 
0
source

If you have Reactive Extensions , you can do this:

 Observable.Return(true) .Delay(TimeSpan.FromSeconds(1)) .Subscribe(_ => DoWork()); 
0
source

All Articles