簡體   English   中英

如何使用計時器替換Azure Worker角色中的Thread.Sleep(...)?

[英]How to use a Timer to replace Thread.Sleep(…) in an Azure Worker Role?

人們說在Azure Worker Role使用Timer而不是Thread.Sleep(...)的例子很多。 沒有問題。

我正在努力理解的是如何對此進行編碼。

目前,我有以下(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) .. fine ..啟動計時器(例如,以30秒為間隔),然后退出該方法。

然后,它返回到該循環中的主Run()方法.. 因此它立即返回並再次進入DoWork()方法..而不是等待計時器將其觸發。

所以我不確定如何用計時器替換任何Thread.Sleep(...)

有什么線索嗎?

澄清

我不想退出Run()方法:)我很高興能永遠循環下去。 我所堅持的是,替換標准的Thread.Sleep(...)調用(阻止線程),並用大多數人建議的Timer替換它。

更新

請不要鏈接或建議我使用cancelSource.Token.WaitHandle.WaitOne(); 作為解決方案。 那不是我要在這里實現的目標。 請注意帖子標題!

我認為,如果要按此處概述的方式解決此問題,則需要一個WaitHandle和一個Timer。

簡短的答案在下面。 長答案成了一篇博客文章: 如何在Thread.Sleep上使用Timer和EventWaitHandle在WorkerRole中等待

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM