Задача службы Windows - отмена опроса - PullRequest
2 голосов
/ 21 марта 2019

Я пишу службу Windows и нашел пример, который предлагает написать службы Windows для опросов следующим образом:

private void Poll()
{
    CancellationToken cancellationPoll = ctsPoll.Token;
    while (!cancellationPoll.WaitHandle.WaitOne(tsInterval))
    {
        PollDatabase();
        // Occasionally check the cancellation state.
        if (cancellationPoll.IsCancellationRequested)
        {
            break;
        }
    }
}

Я немного запутался, когда дело доходит до отмены и если мне нужны оба варианта cancellationPoll.WaitHandle.WaitOne () и cancellationPoll.IsCancellationRequested или они делают то же самое, и требуется только одно?

Ответы [ 3 ]

1 голос
/ 21 марта 2019

!cancellationPoll.WaitHandle.WaitOne(tsInterval) предназначен для обеспечения интервала опроса, поэтому между опросом (+ продолжительность операции) будет не менее tsIntetval:

--tsInterval--|--operation--|--tsInterval--|...

Если вы посмотрите на документацию для CancellationToken.WaitHandle, там написано следующее:

WaitHandle, который сигнализируется при отмене токена.

Так что в вашем случае операции cancellationPoll.IsCancellationRequested достаточно, потому что у вас ничего нет после нее. Но представьте себе такую ​​ситуацию:

while (!cancellationPoll.WaitHandle.WaitOne(tsInterval))
{
    //long operation A

    if (cancellationPoll.IsCancellationRequested)
    {
        break;
    }

    //long operation B

    if (cancellationPoll.IsCancellationRequested)
    {
        break;
    }
    //long operation C
}

В этом случае имеет смысл периодически проверять состояние отмены, чтобы избежать выполнения длительной операции ...

0 голосов
/ 21 марта 2019

Ожидание WaitHanlde здесь избыточно, поскольку с точки зрения результата оно делает то же самое, что и IsCancellationRequested - указывает, что запрос отменен (но делает это немного по-другому). Так что для вашего случая вы можете выбрать один метод: WaitHandle или IsCancellationRequested. Но имейте в виду, что WaitHandle - это IDisposable и требует утилизации связанной CancellationTokenSource. Если вы решите использовать IsCancellationRequested, не забудьте добавить вызов, который должен перепланировать поток, такой как Thread.Sleep, чтобы не чрезмерно использовать ресурсы ЦП. Один из сценариев, когда WaitHanlde может быть применен, это когда вам нужно дождаться дескриптора и вы хотите ввести семантику отмены в это ожидание:

 WaitHandle.WaitAny(new [] { handleToWait, cancellationHandle });
0 голосов
/ 21 марта 2019

!cancellationPoll.WaitHandle.WaitOne(tsInterval) необходим, чтобы вы не ждали все время. WaitOne(tsInterval) вернется либо потому, что токен получил синнал для отмены, либо потому, что время истекло. Если токен получил сигнал для отмены WaitOne(tsInterval), он вернет true и завершит цикл.

Например, если вы сделаете что-то вроде:

while(true)
{
    // long operation
    if (cancellationPoll.IsCancellationRequested)
    {
        break;
    }

    Thread.Sleep(tsInterval);
}

если затем отменяется запрос, в то время как поток блокируется с помощью Thread.Sleep(), вся операция не будет знать, что запрос отменяется не раньше, чем завершится Thread.Sleep() и следующий цикл не достигнет оператора if.

...