private object DoCall() { try { object callResult = xlService_.Call(reference_, args_); return(callResult); } catch (EvaluationException e) { var logMessage = "Error at: " + FunctionLoggerHelper.GetReferenceString(reference_) + @" converted params: " + FunctionLoggerHelper.LogParameters(args_.FunctionName, args_); logService_.WriteError(logMessage, e); return(e.XllResult); } catch (Exception e) { var logMessage = "Error at: " + FunctionLoggerHelper.GetReferenceString(reference_) + @" converted params: " + FunctionLoggerHelper.LogParameters(args_.FunctionName, args_); logService_.WriteError(logMessage, e); var message = ExceptionHelper.GetErrorMessage(args_.FunctionName, e); return(message); } }
/// <summary> /// Starts async UDF calculation. /// Returns Scheduled/Calculating or calculated value. /// Make sure calling UDF marked with IsMacroType=true. /// </summary> public object Calc(CallArguments args) { CheckFuncName(args); MarkUdfNonVolatile(); ExcelReference caller; try { caller = GetCallerExcelReference(); } catch (Exception e) { logService_.WriteError( "Error getting reference. " + FunctionLoggerHelper.LogParameters(args.FunctionName, null), e); // TODO Cleanup return("Error getting reference."); } if (IsNewEvaluationBatchStarted) { OnEvaluatingBatchStarted(); } object[] asyncKeyArgs = GetAsyncKeyArgs(args.RawArgs, caller, batchStarted_); AsyncCallInfo asyncCallInfo = new AsyncCallInfo(args.FunctionName, asyncKeyArgs); if (!IsCalculatingTheSame(caller, asyncCallInfo) || IsScheduled(caller)) { // Check simple case. Precedent is still calculating. Precedents precedents = caller.GetPrecedents(); if (precedents.GetRefs().Any(IsCalculatingAny)) { SetEvalState(caller, EvalState.Scheduled, args, asyncCallInfo); return(Scheduled); } if (ForcePrecedentCalculated(caller, precedents)) { SetEvalState(caller, EvalState.Scheduled, args, asyncCallInfo); return(Scheduled); } } Validate(args); bool isCalculating; object result = Observe(asyncKeyArgs, caller.XlfToReference(), args, out isCalculating); if (isCalculating) { // Async call to service scheduled. SetEvalState(caller, EvalState.ObservableCreated, args, asyncCallInfo); return(Calculating); } else { // Async call to service and result are ready. SetEvalState(caller, EvalState.ObservableFinished, args, asyncCallInfo); return(result); } }