有很多人说在Azure Worker Role
中使用Timer
而不是Thread.Sleep(...)
的例子。这没什么问题。
我很难理解的是如何对其进行编码。
目前,我有以下(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和一个Timer。
下面是简短的答案。长长的答案变成了一篇博客文章:HowTo wait in a WorkerRole using Timer and EventWaitHandle over Thread。睡眠
我使用了EventWaitHandle和Timer,并提出了这个解决方案:
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;
}
}
}