使用计时器提交工作项

重要的 API

了解如何创建在计时器到时后运行的工作项。

创建单次计时器

使用 CreateTimer 方法为工作项创建计时器。 提供完成工作的 lambda,并使用 延迟 参数指定线程池等待的时间,然后才能将工作项分配给可用线程。 延迟是使用 TimeSpan 结构指定的。

注释

在 WinUI 3 应用中,使用 DispatcherQueue.TryEnqueueMicrosoft.UI.Dispatching.DispatcherQueue 中访问 UI 线程并显示工作项的进度。 有关详细信息,请参阅 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 重载以提供其他 lambda。 它在计时器被取消或工作项完成时运行。

以下示例创建一个计时器,该计时器提交工作项,并在工作项完成或计时器取消时调用方法:

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,因为它会阻止调用线程,这会使 UI 在 UI 线程上调用时无响应。 可以改用 ThreadPoolTimer 创建工作项,这会延迟工作项完成的任务,而不会阻止 UI 线程。

有关演示工作项、计时器工作项和定期工作项的完整代码示例,请参阅 线程池示例 。 该代码示例最初是为Windows 8.1编写的,但在Windows 10中可以重用该代码。

有关重复计时器的信息,请参阅 “创建定期工作项”。