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

本文关键字:回调 定时 最简单 NET 方法 什么 | 更新日期: 2023-09-27 17:58:42

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

Thread.Invoke(MyCallback, 1000);

从现在起1次1秒,它只会调用MyCallback。

最简单的方法是什么。NET?我必须设置一个定时器并挂接一个事件吗?

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

您可以使用System。计时器。定时器来做到这一点,而不产生你自己的线程。实现Elapsed回调以执行您想要的操作,设置Enabled true和AutoReset false以实现单个调用。

完成Timer对象后,请确保将其Dispose

这里有一个方法,它使用Timer:在某个超时后运行Action

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");
});
Task.Factory.StartNew(() =>
{
    Thread.Sleep(1000);
    // Do Stuff
});

正如下面的评论所指出的,尽管很容易理解,而且写得很短,但这是一种相对低效/资源匮乏的方法。

只有我的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);

用法:

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

如果你有反应扩展,你可以这样做:

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