@@ -163,25 +163,6 @@ public static string ParamsJoinString(string separator, params string[] values)
163163| A2    | =ParamsFunc2(\" a\" ,,\" c\" ,\" d\" ,,\" f\" )     | a,,c, [ 3: d,ExcelDna.Integration.ExcelMissing,f] 
164164| A3    | =ParamsJoinString(\" //\" ,\" 5\" ,\" 4\" ,\" 3\" ) | 5//4//3
165165
166- ## Array formula  
167- 
168- ``` csharp 
169- [ExcelMapArrayFunction ]
170- public  static  IEnumerable < string >  MapArray (IEnumerable < DateTimeKind >  a )
171- {
172-     return  a .Select (i  =>  " Array element VAL: " +  i .ToString ());
173- }
174- ``` 
175- 
176- | Cell  | Formula            | Result 
177- | ----- | ------------------ | ------ 
178- |  A1    |  Utc                |   
179- |  A2    |  Local              |  
180- |  A3    |  Unspecified        |  
181- | B1    | {=MapArray(A1: A3 )} | Array element VAL: Utc
182- | B2    | {=MapArray(A1: A3 )} | Array element VAL: Local
183- | B3    | {=MapArray(A1: A3 )} | Array element VAL: Unspecified
184- 
185166## Async functions and tasks  
186167
187168``` csharp 
@@ -227,15 +208,15 @@ public class Calc
227208}
228209
229210[ExcelFunction ]
230- public  static  ExcelObjectHandle < Calc >  CreateCalc (double  d1 , double  d2 )
211+ public  static  Calc  CreateCalc (double  d1 , double  d2 )
231212{
232-     return  new ( new  Calc (d1 , d2 ) );
213+     return  new  Calc (d1 , d2 );
233214}
234215
235216[ExcelFunction ]
236- public  static  double  CalcSum (ExcelObjectHandle < Calc >   h )
217+ public  static  double  CalcSum (Calc   c )
237218{
238-     return  h . Object .Sum ();
219+     return  c .Sum ();
239220}
240221``` 
241222
@@ -249,15 +230,15 @@ Thread safe creation and use is supported:
249230
250231``` csharp 
251232[ExcelFunction (IsThreadSafe  =  true )]
252- public  static  ExcelObjectHandle < int >   CreateObjectTS ( int   i )
233+ public  static  Calc   CreateCalcTS ( double   d1 ,  double   d2 )
253234{
254-     return  new ( i );
235+     return  new   Calc ( d1 ,  d2 );
255236}
256237
257238[ExcelFunction (IsThreadSafe  =  true )]
258- public  static  int   UseObjectTS ( ExcelObjectHandle < int >   h )
239+ public  static  double   CalcSumTS ( Calc   c )
259240{
260-     return  h . Object ;
241+     return  c . Sum () ;
261242}
262243``` 
263244
@@ -295,9 +276,9 @@ public class DisposableObject : IDisposable
295276}
296277
297278[ExcelFunction ]
298- public  static  ExcelObjectHandle < DisposableObject >  CreateDisposableObject (int  x )
279+ public  static  DisposableObject  CreateDisposableObject (int  x )
299280{
300-     return  new ( new  DisposableObject () );
281+     return  new  DisposableObject ();
301282}
302283``` 
303284
@@ -381,7 +362,7 @@ Subsequent multiple conversions for the same type (like `TestType1 Order3ToTestT
381362
382363## Function execution handler  
383364
384- Monitor Excel functions execution with a custom handler:
365+ Monitor Excel functions execution with a custom handler, marked with  ` ExcelFunctionExecutionHandlerSelector `  attribute :
385366
386367``` csharp 
387368internal  class  FunctionLoggingHandler  : FunctionExecutionHandler 
@@ -430,4 +411,42 @@ internal class FunctionLoggingHandler : FunctionExecutionHandler
430411        return  new  FunctionLoggingHandler ();
431412    }
432413}
414+ ``` 
415+ 
416+ The default return value for async functions that are in process is #N/A. You can, for example, return the newer #GETTING_DATA error code creating the following function execution handler:
417+ 
418+ ``` csharp 
419+ internal  class  AsyncReturnHandler  : FunctionExecutionHandler 
420+ {
421+     public  override  void  OnSuccess (FunctionExecutionArgs  args )
422+     {
423+         if  (args .ReturnValue .Equals (ExcelError .ExcelErrorNA ))
424+             args .ReturnValue  =  ExcelError .ExcelErrorGettingData ;
425+     }
426+ 
427+     [ExcelFunctionExecutionHandlerSelector ]
428+     public  static  IFunctionExecutionHandler  AsyncReturnHandlerSelector (IExcelFunctionInfo  functionInfo )
429+     {
430+         return  new  AsyncReturnHandler ();
431+     }
432+ }
433+ ``` 
434+ 
435+ ## Function registration processing  
436+ 
437+ You can implement custom function wrappers during registration using ` ExcelFunctionProcessor `  attribute:
438+ 
439+ ``` csharp 
440+ public  interface  IExcelFunctionInfo 
441+ {
442+     ExcelFunctionAttribute  FunctionAttribute  { get ; }
443+     List <IExcelFunctionParameter > Parameters  { get ; }
444+     IExcelFunctionReturn  Return  { get ; }
445+     List <object > CustomAttributes  { get ; }
446+ 
447+     LambdaExpression  FunctionLambda  { get ; set ; }
448+ }
449+ 
450+ [ExcelFunctionProcessor ]
451+ public  static  IEnumerable < IExcelFunctionInfo >  ProcessFunctions (IEnumerable < IExcelFunctionInfo >  registrations , IExcelFunctionRegistrationConfiguration  config )
433452``` 
0 commit comments