Reputation: 113996
How do I create an extension method that can execute a given function later? I've come up with the following code, but it doesn't list in the IntelliSense list when you type MyFunc.DoLater()
.
I've declared the extension method in a static class...
using TTimer = System.Timers.Timer; // to prevent confusion with Windows.Forms.Timer
public static void DoLater(this Action handler, int delay) {
TTimer timer = new TTimer(delay);
timer.Elapsed += delegate {
handler();
timer.Dispose();
};
timer.Start();
}
... and MyFunc
is just a method in a Form
class with no parameters.
public void MyFunc(){
}
Upvotes: 3
Views: 1141
Reputation: 12794
Cast the method as an Action
.
((Action)MyMethod).DoLater(10000);
To use the extension method, the compiler is expecting an object of type Action
. I'm not entirely sure what the difference between a method member and an Action
member is, but I'm guessing there's an explicit conversion from method to Action
.
Upvotes: 1
Reputation: 31743
You need an action instance to execute your extension method on:
var a = new Action(() => MyFunc());
a.DoLater();
But I would suggest a better and more generic approach:
public static class DoLaterExtension
{
public static void DoLater<T>(this T x, int delay, Action<T> action)
{
// TODO: Impelement timer logic
action.Invoke(x);
}
}
private void Example()
{
var instance = new MyForm();
instance.DoLater(1000, x => x.MyFunc());
}
Keep in mind that you should better use a System.Windows.Fomrs.Timer
to avoid thread issues.
Or the TPL way (if you are on .net 4.0 i would suggest that).
public static void DoLater<T>(this T x, int delay, Action<T> action)
{
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(delay);
}).ContinueWith(t =>
{
action.Invoke(x);
}, scheduler);
}
And if you use .net 4.5 you can even use Task.Delay
http://msdn.microsoft.com/en-us/library/hh194845.aspx
Upvotes: 3
Reputation: 2317
Nice idea. I tried it using System.Timers.Timer and it works fine.
static class Program
{
static System.Timers.Timer _timer;
static void Main(string[] args)
{
DoLater(SayHello, 5000);
Console.ReadLine();
}
public static void DoLater(this Action handler, int delay)
{
_timer = new System.Timers.Timer(delay);
_timer.Elapsed += new ElapsedEventHandler(delegate {
handler();
_timer.Dispose();
});
_timer.Enabled = true;
}
public static void SayHello()
{
MessageBox.Show("Hello World");
}
}
Upvotes: 1