Отправка рабочего элемента по таймеру

Важные API

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

Создание однократного таймера

Чтобы создать таймер для рабочего элемента, используйте метод CreateTimer. Определите лямбда-выражение, соответствующее заданию, и используйте параметр delay, чтобы указать, как долго пулу потоков нужно ждать, прежде чем назначить рабочий элемент доступному потоку. Задержка определена с использованием структуры TimeSpan.

ПримечаниеCoreDispatcher.RunAsync можно использовать для доступа к пользовательскому интерфейсу и отображения хода выполнения рабочего элемента.

В следующем примере создается рабочий элемент, который запускается через три минуты:

TimeSpan delay = TimeSpan.FromMinutes(3);
            
ThreadPoolTimer DelayTimer = ThreadPoolTimer.CreateTimer(
    (source) =>
    {
        //
        // TODO: Work
        //
        
        //
        // Update the UI thread by using the UI core dispatcher.
        //
        Dispatcher.RunAsync(
            CoreDispatcherPriority.High,
            () =>
            {
                //
                // UI components can be accessed within this scope.
                //

            });

    }, delay);
TimeSpan delay;
delay.Duration = 3 * 60 * 10000000; // 10,000,000 ticks per second

ThreadPoolTimer ^ DelayTimer = ThreadPoolTimer::CreateTimer(
        ref new TimerElapsedHandler([this](ThreadPoolTimer^ source)
        {
            //
            // TODO: Work
            //
            
            //
            // Update the UI thread by using the UI core dispatcher.
            //
            Dispatcher->RunAsync(CoreDispatcherPriority::High,
                ref new DispatchedHandler([this]()
                {
                    //
                    // UI components can be accessed within this scope.
                    //

                    ExampleUIUpdateMethod("Timer completed.");

                }));

        }), delay);

Предоставление обработчика завершения

Если требуется, обрабатывайте отмену и завершение рабочего элемента с помощью обработчика TimerDestroyedHandler. Чтобы указать дополнительное лямбда-выражение, используйте перегрузку CreateTimer. Это выполняется, когда таймер отменяется или когда рабочий элемент завершается.

В следующем примере создается таймер, который отправляет рабочий элемент и вызывает метод, когда рабочий элемент завершается или происходит отмена таймера:

TimeSpan delay = TimeSpan.FromMinutes(3);
            
bool completed = false;

ThreadPoolTimer DelayTimer = ThreadPoolTimer.CreateTimer(
    (source) =>
    {
        //
        // TODO: Work
        //

        //
        // Update the UI thread by using the UI core dispatcher.
        //
        Dispatcher.RunAsync(
                CoreDispatcherPriority.High,
                () =>
                {
                    //
                    // UI components can be accessed within this scope.
                    //

                });

        completed = true;
    },
    delay,
    (source) =>
    {
        //
        // TODO: Handle work cancellation/completion.
        //


        //
        // Update the UI thread by using the UI core dispatcher.
        //
        Dispatcher.RunAsync(
            CoreDispatcherPriority.High,
            () =>
            {
                //
                // UI components can be accessed within this scope.
                //

                if (completed)
                {
                    // Timer completed.
                }
                else
                {
                    // Timer cancelled.
                }

            });
    });
TimeSpan delay;
delay.Duration = 3 * 60 * 10000000; // 10,000,000 ticks per second

completed = false;

ThreadPoolTimer ^ DelayTimer = ThreadPoolTimer::CreateTimer(
        ref new TimerElapsedHandler([&](ThreadPoolTimer ^ source)
        {
            //
            // TODO: Work
            //

            //
            // Update the UI thread by using the UI core dispatcher.
            //
            Dispatcher->RunAsync(CoreDispatcherPriority::High,
                ref new DispatchedHandler([&]()
                {
                    //
                    // UI components can be accessed within this scope.
                    //

                }));

            completed = true;

        }),
        delay,
        ref new TimerDestroyedHandler([&](ThreadPoolTimer ^ source)
        {
            //
            // TODO: Handle work cancellation/completion.
            //

            Dispatcher->RunAsync(CoreDispatcherPriority::High,
                ref new DispatchedHandler([&]()
                {
                    //
                    // Update the UI thread by using the UI core dispatcher.
                    //

                    if (completed)
                    {
                        // Timer completed.
                    }
                    else
                    {
                        // Timer cancelled.
                    }

                }));
        }));

Отмена таймера

Если таймер еще отсчитывает время, а рабочий элемент больше не нужен, вызовите Cancel. Таймер отменяется, и рабочий элемент не отправляется в пул потоков.

DelayTimer.Cancel();
DelayTimer->Cancel();

Комментарии

Приложения универсальной платформы Windows (UWP) не могут использовать Thread.Sleep, поскольку это может привести к блокированию потока пользовательского интерфейса. Вместо этого для создания рабочего элемента вы можете использовать метод ThreadPoolTimer; в результате задача, выполняемая рабочим элементом, будет отложена без блокировки потока пользовательского интерфейса.

Полный образец кода, демонстрирующего рабочие элементы, рабочие элементы таймеров и периодические рабочие элементы, см. на странице образца пула потоков. Пример кода изначально написан для Windows 8.1, но код можно использовать и в Windows 10.

Дополнительные сведения о повторяющихся таймерах см. в разделе Создание периодического рабочего элемента.