How to use functions as work item delegates (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Learn how to use functions (and function objects) as work item delegates.

The topics in this section use lambdas to show how to run code in thread pool work items, but your app can also delegate the work to functions (and function objects).

What you need to know

Technologies

Prerequisites

Instructions

Using functions as work item delegates in C#

In C#, using a function as a delegate (instead of a lambda) is simple. Define the function with the correct footprint - in this case, TimerElapsedHandler - and create the handler using the name of the delegate function.

  1. The following function defines a work item for use with a timer:

    void WorkItemDelegate(ThreadPoolTimer source)
    {
        // 
        // TODO: Work
        // 
    
        String text = "Periodic delegate work item called\n\n";
    
        // 
        // Update the UI thread by using the UI core dispatcher.
        // 
        Dispatcher.RunAsync(CoreDispatcherPriority.High,
            () =>
            {
                // 
                // UI components can be accessed within this scope.
                // 
                OutputBlock.Text += text;
            });
    }
    
  2. The following code creates a work item using the delegate function:

    TimeSpan period = new TimeSpan(0, 0, 30);
    
    var handler = new TimerElapsedHandler(WorkItemDelegate);
    
    ThreadPoolTimer PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer(handler, period);
    

Using functions as work item delegates in C++

In C++, you can use a function pointer or a functor instead of a lambda. A function pointer is static and it won't have access to any of the resources local to your UI class. Since a functor is a class, it can store references to objects like the UI Core Dispatcher and UI elements that need to be updated by the work item.

  1. Set up the functor class with the necessary properties and an operator() function:

    // 
    // WorkItemFunctor.h
    // 
    
    #pragma once
    
    namespace DelegatesExample
    {
    
        class WorkItemFunctor
        {
        public:
    
            //
            // The constructor takes references to the CoreDispatcher and a
            // XAML TextBlock.
            //
    
            WorkItemFunctor(Windows::UI::Core::CoreDispatcher ^ dispatch, 
                            Windows::UI::Xaml::Controls::TextBlock ^ block) 
                : Dispatcher(dispatch)
                , OutputTextBlock(block)
            {
            }
    
    
            // 
            // This function will be called when the work item runs.
            // 
    
            void operator()(Windows::System::Threading::ThreadPoolTimer^ source) const;
    
        private:
    
            Windows::UI::Core::CoreDispatcher      ^ Dispatcher;
            Windows::UI::Xaml::Controls::TextBlock ^ OutputTextBlock;
        };
    
    }
    
  2. When the work item runs, the operator() function is called, so do the work in that function:

    // 
    // WorkItemFunctor.cpp
    // 
    
    #include "pch.h"
    #include "WorkItemFunctor.h"
    
    using namespace DelegatesExample;
    
    using namespace Platform;
    using namespace Windows::Foundation;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Core;
    using namespace Windows::System::Threading;
    
    
    void WorkItemFunctor::operator()(ThreadPoolTimer^ source) const
    {
    
        // 
        // This example updates a text block by appending a string, to show the
        // use of dispatched UI updates from a functor class.
        // 
    
        String ^ text = "Periodic delegate work item called\n\n";
    
    
        // 
        // 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.
                // 
                OutputTextBlock->Text += text;
            }));
    }
    
  3. The functor is initialized with the core dispatcher and a text block, then the work item is created:

    WorkItemFunctor func(Dispatcher, OutputBlock);
    auto handler = ref new TimerElapsedHandler(func);
    
    TimeSpan period;
    period.Duration = 30 * 10000000; // 10,000,000 ticks per second
    
    ThreadPoolTimer ^ PeriodicTimer = ThreadPoolTimer::CreatePeriodicTimer(handler, period);
    

Quickstart: Submitting a work item to the thread pool

How to submit a work item using a timer

How to create a periodic work item

How to create and use pre-allocated work items

How to respond to named events and semaphores

Best practices for using the thread pool