Hi,
I'm trying to add a custom UltraCalcFunction (GetPrice) that's able to poll periodically for price updates based on an investment identifier in another column. The investment identifier isn't changing, but I need GetPrice() to evaluate periodically anyways in case the price in the price provider has changed.
I thought I could do this by overriding AlwaysDirty to always return true. But it appears that even if a function is AlwaysDirty, it doesn't always get recalculated on the next ultraCalcManager.ReCalc() run.
I've attached a small project that demonstrates the problem. To test this, I'm using the built-in now() function as well as a custom CurrentTime() function that basically returns DateTime.Now. The properties on the UltraCalcManager are all default (asynchronous calculations, freq=10 ms, duration=50ms).
Letting the application sit and run doesn't update either unbound column as I would have expected (since the calc manager should be recalcing every 10 ms). Explicitly calling UltraCalcManager.ReCalc() doesn't do anything either. I have to explicitly DirtyAllFormulas before calling ReCalc for it to work. DirtyAllFormulas is prohibitively expensive for my application because there're many other formulas that should not be dirtied.
Interestingly, changing the sort order triggers an update of the timestamps, but only the first time I change the sort order.
Separately from the above issue where IsAlwaysDirty doesn't seem to really make formulas dirty, I would appreciate any advice you have on how I can periodically poll. Let's say that I only want to poll using GetPrice() every 5 minutes. But I have other formulas that need to respond at a much higher freqency. So I can't just adjust the UltraCalcManager's frequency setting. If IsAlwaysDirty worked as I expect, I would be hammering my price provider many times every second.
I was thinking of tracking the last evaluation time and comparing that to the current time to determine if I should actually do anything in Evaluate. But that doesn't work because every call of Evaluate is made independently and I have no way of knowing that the last evaluation time was for my cell or for a different cell.
Then I thought of trying to check to see if the current time falls into the couple of seconds after the start of an arbitrary 5-minute interval. If so, I poll. Otherwise, I have to return some sort of cached result. I would prefer to not have to set up result caching and just abort the Evaluate, leaving the current value as is. But it appears that I have to always return something, so caching is the best solution that comes to mind.
The problem with the above approach is that if, for whatever reason (other calcs taking a long time?), the calcmanager's misses the small window where polling should occur, you're stuck waiting for another 5 minutes before another window opens. This seems unreliable. Lengthening the window might help, but that also increases the duration under which we're hammering the price provider.
Any suggestions?
Thanks in advance,
-- Yale
I need to have a different Price for each row. NamedReferences aren't associated with controls, so can't be row-specific, right?
What I have done is added a NamedReference, but just so I have something that I can dirty using a timer. So if my custom function is AlwaysDirty, period dirtying of this dummy NamedReference gives it the kick it needs in order to recalculate.
But there're other timers running every 100ms that could possibly (but not always, so I need the NamedReference timer above) change data in the grid. So there could potentially be a dirtying of the calculation network every 100ms, which is much more frequent than I would like to hit my price provider. So I still have the problem I described in the second half of my original post where I want to exit Evaluate() and do nothing some of time. Is there any way to do that?
Thanks.
--yale
The AlwaysDirty formulas are only dirtied when something else in the calc network is dirtied. They are not constantly dirtied on a timer or anything.
If you want a function to be constantly updated, then you will need to use a timer or something to constantly update it.
What I would probably do is - don't use a custom function. Instead, use a NamedReference and use a timer to set the Formula on the NamedReference to the new value at regular intervals.
Oh, I guess that explains the error message the forum gave me. I thought it went through fine because my post made it.
Here's the sample project again.
Hello Yale,
Thanks for provided information, Could you please try to upload your sample again, because I didn`t find it in the thread and I`ll try to reserach your issue.
Thanks in advance!
Regards