我希望在C#(更具体地说,是WPF)中实现类似以下的功能:
Thread.Invoke(MyCallback, 1000);
一秒钟后,将会调用MyCallback函数一次。
在.NET中,最简单的方法是什么?我需要设置一个计时器并挂接事件吗?
Enabled
设置为true,将AutoReset
设置为false以实现单次调用。
确保在使用完 Timer 对象后进行Dispose
处理!
static void Invoke(TimeSpan dueTime, Action action)
{
Timer timer = null;
timer = new Timer(_ => { timer.Dispose(); action(); });
timer.Change(dueTime, TimeSpan.FromMilliseconds(-1));
}
Invoke(TimeSpan.FromSeconds(5), () =>
{
Console.WriteLine("Hello World");
});
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
// Do Stuff
});
如下评论所述,虽然这种方法易于理解且书写简短,但相对来说效率较低,会消耗更多资源。
Timer
使用Windows消息或其他方式来避免这种情况(使用线程)吗? - George Duckett使用方法:
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();
}
}
只是我的个人意见,
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());