Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么';在.NET中进行定时回调最简单的方法是什么?_C#_.net_Wpf - Fatal编程技术网

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

C# 什么';在.NET中进行定时回调最简单的方法是什么?,c#,.net,wpf,C#,.net,Wpf,我想在C#(更具体地说,WPF)中做类似的事情: 从现在起1秒1次调用MyCallback 使用.NET执行此操作的最简单方法是什么?我必须设置计时器并挂接事件吗 Task.Factory.StartNew(() => { Thread.Sleep(1000); // Do Stuff }); 正如下面的评论中所指出的,虽然易于理解且编写简短,但这是一种相对低效/资源匮乏的方法。您可以使用它来完成这项工作,而无需生成自己的线程。实现回调以执行所需操作,设置Enabledt

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

从现在起1秒1次调用MyCallback

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

Task.Factory.StartNew(() =>
{
    Thread.Sleep(1000);
    // Do Stuff
});
正如下面的评论中所指出的,虽然易于理解且编写简短,但这是一种相对低效/资源匮乏的方法。

您可以使用它来完成这项工作,而无需生成自己的线程。实现回调以执行所需操作,设置
Enabled
true和
AutoReset
false以实现单个调用


确保
Dispose
处理完
Timer
对象

下面是一个方法,该方法在特定超时后使用:

我不确定计时器到底有多轻,但它应该比阻塞线程池线程要好

用法:

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

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

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();
    }
}
只要我的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);
如果您已经获得了,您可以这样做:

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

我不认为这有多糟糕,它不会占用很多资源,线程等待也不会占用CPU时间。我想定时器会占用更多的资源。我有一个实用程序包装器,它使用System.Threading.timer,但这是一个相当干净的方法。正如Kirk提到的,它会阻塞线程池线程,所以如果您在许多地方使用这种模式,您可能不想使用它。在最坏的情况下,您可能会耗尽线程池(特别是在延迟时间较长的情况下),回调的执行时间将比您预期的要晚得多;在什么都不做的情况下使用一大块地址空间是没有意义的。考虑到整个线程池的线程是有限的,当一个线程可能在做其他事情时,让它在一秒钟内什么也不做是没有意义的。@Dan,这是真的,没有想到线程池的线程已经用完了等等。
计时器是使用windows消息传递还是避免这种事情(使用线程)好的,丹,蒂姆,柯克。我站在更正,我的答案肯定不是最好的方式(将编辑答案)。幸运的是,奥普找到了最简单的方法PI很有兴趣看到将其包装成一种方法的代码,该方法采取了动作并延迟。对不起@George,我手头没有这样一个固定的包装器。@George I和至少一个其他回答者已经发布了可能的实现。@Jay,非常感谢他们。我在没有评论的情况下发布了该评论。:)是我还是最近出现了大量与计时器相关的问题?
 WaitableWorker worker=new WaitableWorker(3000,DoWork);
Observable.Return(true)
    .Delay(TimeSpan.FromSeconds(1))
    .Subscribe(_ => DoWork());