如何使用定时器来代替了Thread.Sleep(...)在Azure中工作者角色?定时器、如何使用、工作者、角色

2023-09-03 06:13:16 作者:无名指的等待

有很多人说用例子定时器而不是 Thread.sleep代码(...)的Azure工作者角色。没有probs这一点。

There's plenty of examples of people saying to use a Timer instead of Thread.Sleep(...) in an Azure Worker Role. No probs with that.

我正在努力理解是如何$ C C此$。

What I'm struggling to understand is how to code this.

目前,我有以下的(pseduo code)

Currently, I have the following (pseduo code)

_timer.Elapsed += (sender, args) => DoWork();

public override void Run()
{
    while(true)
    {
        DoWork();
    }
}

public void DoWork()
{
    try
    {
        _timer.Stop();

        // Now - do stuff ....

     }
     catch(....) { ... }

     _timer.Start()
}

和发生的事情,就是code进入,一旦的DoWork()方法和 DoesStuff(TM) ..很好..启动计时器(说..用30秒的时间间隔),然后退出该方法。

And what happens, is that the code enters the DoWork() method once and DoesStuff(tm).. fine .. starts the timer (say .. with a 30 second interval) and then exits that method.

然后,返回到主运行()办法..这是该循环。因此,它的立即回来四周,再次进入的DoWork()方法..而不是等待定时器触发其关闭。

Then, it returns back to the main Run() method .. which is in that loop. So it immediately comes back around and enters the DoWork() method again .. instead of waiting for the timer to fire it off.

所以,我不知道如何更换任何 Thread.sleep代码(...)带定时器。

So I'm not sure how to replace any Thread.Sleep(...) with Timers.

任何线索?

我不想退出运行()方法:)我很高兴能继续循环下去。什么我坚持了,正在取代标准的 Thread.sleep代码(...)通话(其中阻塞线程),并替换了定时器,其中大多数人认为。

I do not want to exit the Run() method :) I'm very happy to keep looping forever. What I'm stuck with, is replacing the standard Thread.Sleep(...) call (which blocks the thread) and replace that with a Timer, which most people suggest.

请不要链接或提示,我应该使用 cancelSource.Token.WaitHandle.WaitOne(); 作为解决方案。这不是我想要在这里实现。请注意,文章标题!

Please do not link or suggest that I should use cancelSource.Token.WaitHandle.WaitOne(); as a solution. That is not what I'm trying to achieve here. Please note the post title!

推荐答案

我认为,如果你想解决这个情况下,你勾勒出在这里,你将需要的WaitHandle和定时器的方式。

I figure that if you want to solve this situation the way you outline here you will need a WaitHandle AND a Timer.

简短的答案就在这里下面。长的答案成为了一个博客文章:HowTo等待使用定时器和一个的EventWaitHandle在WorkerRole Thread.sleep代码

The short answer is here below. The long answer became a blog post: HowTo wait in a WorkerRole using Timer and EventWaitHandle over Thread.Sleep

我用了一个的EventWaitHandle随着定时器和想出了这个解决方案:

I used an EventWaitHandle along with the Timer and came up with this solution:

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