Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用计时器替换Azure Worker角色中的Thread.Sleep(…)?_C#_.net_Azure_Timer_Azure Worker Roles - Fatal编程技术网

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;
        }
    }
}