C# 如何使用计时器替换Azure Worker角色中的Thread.Sleep(…)?
有很多人说在C# 如何使用计时器替换Azure Worker角色中的Thread.Sleep(…)?,c#,.net,azure,timer,azure-worker-roles,C#,.net,Azure,Timer,Azure Worker Roles,有很多人说在Azure工作者角色中使用计时器而不是线程。睡眠(…)。没问题 我很难理解的是如何编写代码 目前,我有以下(PSEDOO代码) 然后,代码进入DoWork()方法一次,然后DoesStuff(tm)。。好的启动计时器(例如,间隔30秒),然后退出该方法 然后,它返回主Run()方法。。在那个循环中。因此它会立即返回并再次进入DoWork()方法。。而不是等待计时器启动 所以我不知道如何用计时器替换任何线程.Sleep(…) 有什么线索吗 澄清 我不想退出Run()。我一直坚持的是,替
Azure工作者角色中使用计时器而不是线程。睡眠(…)
。没问题
我很难理解的是如何编写代码
目前,我有以下(PSEDOO代码)
然后,代码进入DoWork()
方法一次,然后DoesStuff(tm)
。。好的启动计时器(例如,间隔30秒),然后退出该方法
然后,它返回主Run()
方法。。在那个循环中。因此它会立即返回并再次进入DoWork()
方法。。而不是等待计时器启动
所以我不知道如何用计时器替换任何线程.Sleep(…)
有什么线索吗
澄清
我不想退出Run()。我一直坚持的是,替换标准的线程。Sleep(…)
调用(阻止线程)并替换为计时器,这是大多数人建议的
更新
请不要链接或建议我使用cancelSource.Token.WaitHandle.WaitOne()代码>作为解决方案。这不是我在这里想要实现的。请注意文章标题 我想如果你想用你在这里概述的方式解决这个问题,你需要一个WaitHandle和一个计时器
下面是简短的答案。长篇大论的答案变成了一篇博文:
我将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;
}
}
}
将DoWork()置于无限循环之外,并将好的旧Thread.Sleep(10000)放入该循环中如何。我们的想法是只初始化计时器一次,您可以在Run()方法中进行初始化。您是否阅读了关于替换Thread.Sleep(…)
的开头行,因为它不好(tm)?如果我理解正确,我们的想法是WorkerRole永远不会从Run()方法中出现,否则您的工作角色将重新启动()。我想我不明白的是为什么这是个坏主意?您是否正在寻找希望每30秒调用一次“DoStuff()”的功能?啊,对不起。好的,我不想退出Run()方法(因此您是正确的)。但是我不想使用Thread.Sleep(..)
来“暂停”工作人员(一段时间)。取而代之的是,我想用一个计时器。这个问题的第一个搜索结果给出了另一个非常优雅的答案,你只需在“做事情”部分启动计时器,标记为重复问题。哦,哇!非常感谢你,今晚回家后我会试一试的/注意:我也喜欢你的高级解决方案(在你的博客上),它使用时间间隔:)也非常有趣!
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;
}
}
}