3

如何创建可以稍后执行给定函数的扩展方法?我想出了以下代码,但是当您键入MyFunc.DoLater().

我已经在静态类中声明了扩展方法......

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();
}

...并且MyFunc只是一个Form没有参数的类中的方法。

public void MyFunc(){
}
4

3 回答 3

3

您需要一个操作实例来执行您的扩展方法:

var a = new Action(() => MyFunc());
a.DoLater();

但我会建议一种更好、更通用的方法:

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());
}

请记住,您最好使用 aSystem.Windows.Fomrs.Timer来避免线程问题。或 TPL 方式(如果您使用的是 .net 4.0,我建议您这样做)。

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);
}

如果您使用 .net 4.5,您甚至可以使用Task.Delay http://msdn.microsoft.com/en-us/library/hh194845.aspx

于 2013-03-14T09:17:42.313 回答
1

好主意。我使用 System.Timers.Timer 进行了尝试,它工作正常。

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");
    }
}
于 2013-03-14T09:19:51.857 回答
1

将该方法转换为Action.

((Action)MyMethod).DoLater(10000);

要使用扩展方法,编译器需要一个类型为 的对象Action。我不完全确定方法成员和Action成员之间的区别是什么,但我猜有一个从方法到Action.

于 2013-03-15T00:48:10.083 回答