April 2nd, 2025

Adding delays to our task sequencer, part 1

Suppose you want to use the task_sequencer class we created a while back (and which we fixed not too long ago), but you also want to implement a rudimentary form of throttling, so that tasks run at a specified maximum rate.

Suppose for concreteness that you want to have a 1-second cooling off period before the next task runs. How would we add this to our task_sequencer?

Well, the thing that kicks off the next task is the completer, which calls complete() on the chained task to trigger the start of the next task. All we have to do is delay that completion. For that, we can use fire_and_forget.

struct task_sequencer
{
    ⟦ ... ⟧

    struct completer
    {
        ~completer()
        {
            complete_later(std::move(chain));
        }
        std::shared_ptr<chained_task> chain;

        static fire_and_forget complete_later(  
            std::shared_ptr<chained_task> chain)
        {                                       
            co_await winrt::resume_after(1s);   
            chain->complete();                  
        }                                       
    };

    ⟦ ... ⟧
};

Instead of calling chain->complete() immediately from the destructor, we kick off a coroutine that calls it after waiting one second.

This coroutine is simple enough you might find it easier to inline it, so that all the logic is in one place.

struct task_sequencer
{
    ⟦ ... ⟧

    struct completer
    {
        ~completer()
        {
            [](auto chain) -> winrt::fire_and_forget {
                co_await winrt::resume_after(1s);     
                chain->complete();                    
            }(std::move(chain));                      
        }
        std::shared_ptr<chained_task> chain;
    };

    ⟦ ... ⟧
};

Maybe instead of waiting one second between the completion of one operation and the start of the next, you want to wait one second between the start of one operation and the start of the next. We’ll look at that next time.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments