使用計時器提交工作項目

重要 API

學習如何建立一個在計時器結束後仍會執行的工作項目。

製作單發計時器

使用 CreateTimer 方法為該工作項目建立計時器。 提供一個完成該工作的 lambda,並使用 delay 參數指定執行緒池等待多久才能將工作項目指派到可用執行緒。 延遲是透過 TimeSpan 結構來指定。

Note

在 WinUI 3 應用程式中,使用 DispatcherQueue.TryEnqueue from Microsoft.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 中重複使用。

關於重複計時器的資訊,請參見 建立週期性工作項目