Использование Thread.Sleep или Timer в рабочей роли Azure в .NET? - PullRequest
9 голосов
/ 05 марта 2012

Я понимаю, что в службе Windows лучше использовать Timer, а не Thread.Sleep(timeout).Однако во всех примерах кода, которые я мог найти в Интернете для работы с рабочими Azure, вместо Timer используется Thread.Sleep(timeout). Даже код по умолчанию, указанный в шаблоне проекта Worker в VisualStudio использует Thread.Sleep:

public class WorkerRole : RoleEntryPoint
{
    public override void Run()
    {
        // This is a sample worker implementation. Replace with your logic.
        Trace.WriteLine("$projectname$ entry point called", "Information");

        while (true)
        {
            Thread.Sleep(10000);
            Trace.WriteLine("Working", "Information");
        }
    }
// ...
}

До сих пор я также использовал Thread.Sleep в своих работниках, но не понимал почему.Поэтому у меня такой вопрос: почему вместо рабочей таблицы Timer используется Thread.Sleep(timeout) в рабочей роли Azure?В чем разница между службой Windows и рабочим Azure, которая приводит к этой разнице в том, как мы должны создавать такие приложения?Хорошо или плохо использовать Timer в работниках Azure?

Любые объяснения со ссылками на некоторые ресурсы, объясняющие основы этого, приветствуются, так как я до сих пор ничего не смог найти.

1 Ответ

15 голосов
/ 06 марта 2012

Целью цикла Thread.Sleep() является предотвращение выхода из метода Run().Если Run() выйдет, то ваш работник перезапустится.Я не знаю, что вы могли бы достичь этой цели эффективно с таймером.

Скорее всего, ваш процессор тратит крошечное количество времени на пробуждение этого потока каждые 1000 мсек, чтобы ничего не делать.Я сомневаюсь, что это важно, но это меня и подвело.Мое решение состояло в том, чтобы ждать вместо CancellationToken.

public class WorkerRole : RoleEntryPoint {
    CancellationTokenSource cancelSource = new CancellationTokenSource();

    public override void Run()
    {
        //do stuff
        cancelSource.Token.WaitHandle.WaitOne();
    }

    public override void OnStop()
    {
        cancelSource.Cancel();
    }
}

Это предотвращает выход из метода Run (), не тратя процессорное время на ожидание занятости.Вы также можете использовать CancellationToken в другом месте вашей программы, чтобы инициировать любые другие операции выключения, которые вам могут понадобиться.

...