在.NET中进行定时回调的最简单方法是什么?

时间:2011-06-09 14:37:40

标签: c# .net wpf

我想在C#(更具体地说,WPF)中做这样的事情:

Thread.Invoke(MyCallback, 1000);

从现在开始,1次,1秒钟即可调用MyCallback。

使用.NET执行此操作的最简单方法是什么?我是否必须设置定时器并挂钩事件?

6 个答案:

答案 0 :(得分:6)

您可以使用System.Timers.Timer执行此操作,而不会生成自己的主题。实现Elapsed回调以执行您想要的操作,将Enabled设置为true并将AutoReset设置为false以实现单个调用。

完成后,请确保Dispose Timer对象!

答案 1 :(得分:3)

以下是使用Action在特定超时后运行Timer的方法:

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

我不确定Timer究竟有多轻量级,但它应该比阻塞ThreadPool线程更好。

用法:

Invoke(TimeSpan.FromSeconds(5), () =>
{
    Console.WriteLine("Hello World");
});

答案 2 :(得分:2)

Task.Factory.StartNew(() =>
{
    Thread.Sleep(1000);
    // Do Stuff
});

正如下面的评论所指出的那样,虽然易于理解且写作也很短,但这是一种相对低效/资源匮乏的方式。

答案 3 :(得分:0)

用法:

Delay.Invocation(MyCallback, 1000);

//or

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

打包机:

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

答案 4 :(得分:0)

只需2美分,

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

    }

<强>用法

 WaitableWorker worker=new WaitableWorker(3000,DoWork);

答案 5 :(得分:0)

如果你有Reactive Extensions,你可以这样做:

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