There are many enhancements you may choose to add to the model. Some of the most obvious are discussed below.
If a function returns multiple results, you should have a single add-in function for each distinct result; the functions will vary only in that they will extract different output data members from the data object.
The cache could be saved to disk whenever the add-in is closed - i.e. during OnXllClose(). One might choose to stream it to a binary file, or more usefully, store it in a database.
When designing the serialization mechanism, it is worth remembering that there may be multiple instances of Excel open, each of them with a separate in-memory cache. Thus, when saving the in-memory cache, it is advisable to perform the following steps as a single atomic operation.
If you have multiple functions in a single add-in which you wish to run asynchronously, you should have multiple caches in a single add-in. Each cache should use a different named channel. For example, if the new function BarrierOptValue() was added to the add-in, it would use a new data object class, e.g. BarrierOptData, a new cache class BarrierOptDataCache and an instance of BarrierOptDataCache in the application class CAvgOptApp.
Most important, when the worker thread for the BarrierOptData object completed, it should use a different channel to inform RTD of its completion, e.g.:
void __stdcall BarrierOptValue_threadfn(void* pvData) { BarrierOptData* args = (BarrierOptData*)pvData; args->Evaluate(); args->done = true; psl::XllRtdSharedData::IncrementChannelSeqNum("BarrierOpt"); }
In addition, the cell containing the sequence number passed to BarrierOptValue() should contain the appropriate channel name, e.g.:
=RTD("XllRtdLink.XllRtdSeqNumServer",,"BarrierOpt")
This pattern will keep updates of the two functions separate from each other.