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