如何使用定时器在Azure中Worker角色替换的Thread.Sleep(...)?(How to

2019-07-19 07:20发布

有很多人说用一个例子Timer来代替Thread.Sleep(...)Azure Worker Role 。 没有与probs。

我正在努力理解是如何实现代码。

目前,我有以下的(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(); 作为解决方案。 这不是我想要在这里实现。 请注意,帖子标题!

Answer 1:

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

简短的回答是这里的下方。 长的答案成为了一个博客文章: 在WorkerRole使用定时器和的EventWaitHandle超过了Thread.Sleep方法文档等待

我用的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;
        }
    }
}


文章来源: How to use a Timer to replace Thread.Sleep(…) in an Azure Worker Role?