FunctionExecutionHandlers Called Twice

20 views
Skip to first unread message

Tom Baxter

unread,
Sep 20, 2023, 3:14:37 PMSep 20
to Excel-DNA
Govert, and others,

I'm using .NET 6 and Excel 365 with FunctionExecutionHandlers on an async UDF (i.e., decorated with ExcelAsyncFunction), although the behavior is the same if the UDF is not async.

Below I have a little schematic that shows the fact that the OnEntry(), OnSuccess() and OnExit() all get called twice. Why are they getting called twice? I need to reliably differentiate the OnEntry(), OnSuccess() and OnExit() marked with asterisks from the non-asterisk-marked ones.

Even if I remove the async service call and replace ExcelAsyncFunction with ExcelFunction , I see the same behavior.

Here is the sequence of calls I am seeing when calling an async service:

*OnEntry() completes
UDF begins execution
UDF awaits an async service call
While awaiting the service call...
   OnSuccess() completes
   OnExit()  completes 
After async service call completes, UDF runs to completion
OnEntry() completes  (again)
*OnSuccess() completes   (again)
*OnExit() completes  (Again)

If I remove the async service call, we still end up with this schematic:

OnEntry() completes
UDF runs to completion
OnSuccess() completes  
OnExit() runs (before UDF has completed)
OnEntry() completes 
OnSuccess() completes 
OnExit() completes 


Govert van Drimmelen

unread,
Sep 20, 2023, 3:28:18 PMSep 20
to exce...@googlegroups.com

Hi Tom,

 

Can you check with a simple function like this:

 

public static object GetValues()

{

    return new object[,] { { 1, 2}, { "abc", "def" }  };
}

 

I don’t expect  it to be called twice.

 

If your function is being wrapped as an async function (so if your function is returning Task<T> and being processed by the Registration helper) then it will be called twice, even if it does no async work internally. That is a consequence of the RTD-based implementation that we use for async functions.

The first time it runs, it initiates the async call, then the async call completes, notifies Excel that the call is complete (which invalidates the calling cell(s)) and then Excel recalculates those cells, which call the function again, this time returning the value.

 

You can somewhat distinguish the calls by looking at the return value – it would be #N/A (ExcelError.ExcelErrorNA) for the first call, and an actual value for the second.

 

-Govert

--
You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/exceldna/8f35d2a7-d02d-4e11-a269-6e5d4c13aac2n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages