我想在C#(更具体地说,WPF)中做这样的事情:
Thread.Invoke(MyCallback, 1000);
从现在开始,1次,1秒钟即可调用MyCallback。
使用.NET执行此操作的最简单方法是什么?我是否必须设置定时器并挂钩事件?
答案 0 :(得分:6)
您可以使用System.Timers.Timer执行此操作,而不会生成自己的主题。实现Elapsed回调以执行您想要的操作,将Enabled
设置为true并将AutoReset
设置为false以实现单个调用。
完成后,请确保Dispose
Timer
对象!
答案 1 :(得分:3)
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());