C++ Asynchronous Delegate for Microsoft Windows
by RyuK ( )
Dec 22, 2007
Microsoft Windows 2000 and later have a very useful system function to make an asynchronous function
call, QueueUserWorkItem.
With this function and its thread
pool that is aware of what Windows is actually doing at a given time, Windows takes care of all asynchronous
function call complicatedness for you in the simplest form. This high-level function is a god-send
for lazy programmers who want to concentrate on what an application can do in a reasonable performance
range rather than how it does things with the smallest performance hit.
But people can never be lazy enough, setting it up with context
information each time will soon become a boring task especially when you want to asynchronously call
a member function of a foreign C++ object. But you don't want to make it completelly dynamic,
either. You have to manually write a wrapper function since QueueUserWorkItem is
a mere C function that knows jack about C++.
This article introduces a small toolkit AsyncDelegate.h that lends itself to solving this
issue by using C++ templates.
To use AsyncDelegate.h, first you declare an asynchronously called member function
and define an inner class for context information. This inner class can have a ctor/dtor if you want
them.
|
X::callbackY is defined like this in a .cpp file:
|
Now you can activate it anywhere you want where a pointer to a target X object is available.
|
X::callbackY is called in the context of the specific X object p with
a ContextY object
as a parameter. In other words, AsyncDelegate.h is a tool to do deferred
execution of this member function call.
|
Let's take a look at the actual AsyncDelegate.h.
|
AsyncDelegateContextHeader is inserted before a context object as a hidden header information
that knows to which object this call belongs to.
|
This class cast a void parameter into T and destructs at the end of a function call.
|
MemFunPointerCreator is a class to make a C++ member function pointer type from 2 template parameter types. This class is required to put a member function pointer in the template parameters of queueUserWorkItemThreadProc.
|
This function template creates a function called by QueueUserWorkItem. A C++ member
function pointer created by MemFunPointerCreator is set as a non-type template parameter.
|
This is the main class exposed to a user. When bLong is true QueueUserWorkItem is
called with WT_EXECUTELONGFUNCTION that implies spawning a new thread which is the default
behavior of this tool.
|
It may be counter-intuitive to call this tool a "delegate" as it doesn't support copy and other smart pointer properties, but it's OK for me because its usage is to kick a worker thread immediately.
