有很多人说用一个例子Timer
来代替Thread.Sleep(...)
在Azure Worker Role
。 没有与probs。
我正在努力理解是如何实现代码。
目前,我有以下的(pseduo代码)
_timer.Elapsed += (sender, args) => DoWork();
public override void Run()
{
while(true)
{
DoWork();
}
}
public void DoWork()
{
try
{
_timer.Stop();
// Now - do stuff ....
}
catch(....) { ... }
_timer.Start()
}
和发生什么事,是代码进入DoWork()
方法和一次DoesStuff(tm)
..很好..启动定时器(比方说..用30秒间隔),然后退出该方法。
然后,它返回到主Run()
方法..这是在该循环。 因此,它马上回来四周,进入DoWork()
再次方法..而不是等待定时器触发其关闭。
所以,我不知道如何更换任何Thread.Sleep(...)
用定时器。
任何线索?
澄清
我不想退出Run()
方法:)我很高兴能永远保持循环。 我坚持着,被替换的标准是什么Thread.Sleep(...)
调用(阻塞线程),并替换成一个Timer
,其中大多数人建议。
更新
请不要链接或提示,我应该使用cancelSource.Token.WaitHandle.WaitOne();
作为解决方案。 这不是我想要在这里实现。 请注意,帖子标题!
我认为,如果你想解决这个情况下,你在这里勾勒出你需要一个WaitHandle的和定时器的方式。
简短的回答是这里的下方。 长的答案成为了一个博客文章: 在WorkerRole使用定时器和的EventWaitHandle超过了Thread.Sleep方法文档等待
我用的EventWaitHandle与定时器一起,并用此溶液想出了:
public class WorkerRole : RoleEntryPoint
{
Waiter waiter;
public override bool OnStart()
{
waiter = new Waiter(WorkerConfiguration.WaitInterval);
return base.OnStart();
}
public override void Run()
{
while (true)
{
DoWork();
waiter.Wait();
}
}
public void DoWork()
{
// [...]
}
}
这里是服务员类:
public class Waiter
{
private readonly Timer timer;
private readonly EventWaitHandle waitHandle;
public Waiter(TimeSpan? interval = null)
{
waitHandle = new AutoResetEvent(false);
timer = new Timer();
timer.Elapsed += (sender, args) => waitHandle.Set();
SetInterval(interval);
}
public TimeSpan Interval
{
set { timer.Interval = value.TotalMilliseconds; }
}
public void Wait(TimeSpan? newInterval = null)
{
SetInterval(newInterval);
timer.Start();
waitHandle.WaitOne();
timer.Close();
waitHandle.Reset();
}
private void SetInterval(TimeSpan? newInterval)
{
if (newInterval.HasValue)
{
Interval = newInterval.Value;
}
}
}