我了解在Windows服务中,最好使用Timer
而不是Thread.Sleep(timeout)
。但是,在我可以在互联网上找到的处理Azure工作人员的所有代码示例中,使用的是Thread.Sleep(timeout)
而不是Timer
。
即使Visual Studio中的Worker项目模板中提供的默认代码也使用Thread.Sleep
:
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("$projectname$ entry point called", "Information");
while (true)
{
Thread.Sleep(10000);
Trace.WriteLine("Working", "Information");
}
}
// ...
}
到目前为止,我一直在我的工作人员中使用Thread.Sleep
,但却没有真正了解原因。所以我的问题是,为什么在Azure辅助角色而不是Thread.Sleep(timeout)
中使用Timer
? Windows服务和Azure工作人员之间的区别是什么导致我们应该如何构思这种应用程序?在Azure工作者中使用Timer
是好还是坏?
由于到目前为止我找不到任何资料,所以任何有关解释其基本原理的资源链接的解释都是受欢迎的。
答案 0 :(得分:15)
Thread.Sleep()
循环的目的是防止Run()
方法退出。如果Run()
退出,那么您的工作人员将重新启动。我不知道你可以用Timer有效地实现这个目标。
你的CPU很可能每1000毫秒就浪费一些时间来唤醒该线程,以便什么都不做。我怀疑这很重要,但它也让我感到烦恼。我的解决方案是等待CancellationToken。
public class WorkerRole : RoleEntryPoint {
CancellationTokenSource cancelSource = new CancellationTokenSource();
public override void Run()
{
//do stuff
cancelSource.Token.WaitHandle.WaitOne();
}
public override void OnStop()
{
cancelSource.Cancel();
}
}
这样可以防止Run()方法退出,而不会在忙碌的等待中浪费CPU时间。您还可以使用程序中其他位置的CancellationToken来启动您可能需要执行的任何其他关闭操作。