2

有很多人说使用 aTimer而不是Thread.Sleep(...)in 的例子Azure Worker Role。没有问题。

我正在努力理解的是如何编码。

目前,我有以下(伪代码)

_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大多数人建议的 a 。

更新

请不要链接或建议我应该cancelSource.Token.WaitHandle.WaitOne();用作解决方案。这不是我想要在这里实现的。请注意帖子标题!

4

1 回答 1

6

我认为,如果您想按照您在此处概述的方式解决这种情况,您将需要一个 WaitHandle 和一个计时器。

简短的答案在下面。长答案变成了一篇博文:HowTo wait in a WorkerRole using Timer and EventWaitHandle over Thread.Sleep

我将 EventWaitHandle 与 Timer 一起使用,并提出了以下解决方案:

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;
        }
    }
}
于 2013-02-06T22:26:26.510 回答