Отправка рабочего элемента с помощью таймера

Важные API

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

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

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

Note

В приложениях WinUI 3 используйте DispatcherQueue.TryEnqueue из Microsoft.UI.Dispatching.DispatcherQueue для доступа к потоку пользовательского интерфейса и отображения хода выполнения из рабочего элемента. Дополнительные сведения см. в обзоре DispatcherQueue .

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

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.
                    }

                }));
        }));

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

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

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

Комментарии

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

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

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