This discussion of handles has focused on the RTD handle implementation, since this is the most efficient and also the most flexible implementation.
As discussed earlier, another set of implementations are available, which use an unsynchronized cache, instead of the synchronized cache used by RTD. They are all very similar to each other, and differ only in how the handle is displayed.
Extension | Handle format | Example |
---|---|---|
NumericHandles.xpe | Address | 66145697 |
StringHandles.xpe | Class:Index | MyObject:3 |
StringPtrHandles.xpe | Class:Address | MyObject:66145697 |
The cache used by the RTD implementation receives a message from Excel whenever a handle goes out of use. It immediately destroys the object and removes it from the cache. As a result, the use of memory and the speed of the implementation remains constant. (We refer to this as a synchronized cache.)
These alternative implementations do not receive a message when a handle is no longer used, and therefore do not know when to destroy it. The cache grows in size until Excel is closed, or until the user decides to clear it. (We refer to this as an unsynchronized cache.)
These unsynchronized implementations have three advantages over the RTD implementations:
RtdHandleServer.dll
, to be deployed and registered
on users' machines.There are also significant disadvantages in using the unsynchronized handle implementations:
There are two additional "house-keeping" tasks that need to be managed in a handle add-in that uses these unsynchronized handles.
The handle values saved in a workbook are irrelevant when the workbook is reopened. Since they are, in effect, pointers, there is no guarantee that the memory pointed to is still valid, and still contains an object of the right type. Worse still, the pointer may be for an object of the right type, but out of date, so that the results are erroneous.
So, we must make sure that all the handles in a workbook are recalculated
when the workbook is reopened. The HandleCache object contains
an event observer object (m_workbookOpenObserver
) which
handles this by trapping the
WorkbookOpen event, and
using a CXlFormulaRefresh object
to update all cells containing a handle creator function.
All this is dealt with by the code generated by the XLL+ Function Wizard. The developer does not need to add any code.
If Excel stays open for long periods, and many object handles are created over time, it is sensible to clear out all the handles in the cache from time to time.
You should provide a menu command that clears the handle cache thus:
psl::ClearHandleCache<Thing>();
You can find an example of this in the NumericHandleDemo sample.
Note that if you have used a results cache, you need to make sure that you clear the results cache first, and then clear all the handles:
CXlOper* Thing_ClearCache_Impl(CXlOper& xloResult) { // End of generated code //}}XLP_SRC ::XllGetTypedApp()->m_cache.Clear(); psl::ClearHandleCache<Thing>(); return xloResult.Ret(); }