public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { if (instance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNoServiceObject))); } if (inputs == null) { if (this.InputParameterCount > 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceNull, this.InputParameterCount))); } } else if (inputs.Length != this.InputParameterCount) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceInvalid, this.InputParameterCount, inputs.Length))); } this.outputs = EmptyArray.Allocate(this.OutputParameterCount); AsyncMethodInvoker.StartOperationInvokePerformanceCounters(this.taskMethod.Name); IAsyncResult returnValue; bool callFailed = true; bool callFaulted = false; ServiceModelActivity activity = null; try { Activity boundActivity = null; AsyncMethodInvoker.CreateActivityInfo(ref activity, ref boundActivity); AsyncMethodInvoker.StartOperationInvokeTrace(this.taskMethod.Name); using (boundActivity) { if (DiagnosticUtility.ShouldUseActivity) { string activityName = SR.GetString(SR.ActivityExecuteMethod, this.taskMethod.DeclaringType.FullName, this.taskMethod.Name); ServiceModelActivity.Start(activity, activityName, ActivityType.ExecuteUserCode); } object taskReturnValue = this.InvokeDelegate(instance, inputs, this.outputs); if (taskReturnValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("task"); } else if (this.isGenericTask) { returnValue = (IAsyncResult)this.toAsyncMethodInfo.Invoke(null, new object[] { taskReturnValue, callback, state }); } else { returnValue = ((Task)taskReturnValue).AsAsyncResult(callback, state); } callFailed = false; } } catch (System.Security.SecurityException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException()); } catch (Exception e) { TraceUtility.TraceUserCodeException(e, this.taskMethod); if (e is FaultException) { callFaulted = true; callFailed = false; } throw; } finally { ServiceModelActivity.Stop(activity); // Any exception above means InvokeEnd will not be called, so complete it here. if (callFailed || callFaulted) { AsyncMethodInvoker.StopOperationInvokeTrace(callFailed, callFaulted, this.TaskMethod.Name); AsyncMethodInvoker.StopOperationInvokePerformanceCounters(callFailed, callFaulted, this.TaskMethod.Name); } } return(returnValue); }
private async Task <Tuple <object, object[]> > InvokeAsync(object instance, object[] inputs) { EnsureIsInitialized(); if (instance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNoServiceObject))); } if (inputs == null) { if (this.inputParameterCount > 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceNull, this.inputParameterCount))); } } else if (inputs.Length != this.inputParameterCount) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceInvalid, this.inputParameterCount, inputs.Length))); } object[] outputs = EmptyArray.Allocate(this.outputParameterCount); AsyncMethodInvoker.StartOperationInvokePerformanceCounters(this.taskMethod.Name); object returnValue; ServiceModelActivity activity = null; Activity boundActivity = null; try { AsyncMethodInvoker.CreateActivityInfo(ref activity, ref boundActivity); AsyncMethodInvoker.StartOperationInvokeTrace(this.taskMethod.Name); if (DiagnosticUtility.ShouldUseActivity) { string activityName = SR.GetString(SR.ActivityExecuteMethod, this.taskMethod.DeclaringType.FullName, this.taskMethod.Name); ServiceModelActivity.Start(activity, activityName, ActivityType.ExecuteUserCode); } OperationContext.EnableAsyncFlow(); returnValue = this.invokeDelegate(instance, inputs, outputs); if (returnValue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("task"); } var returnValueTask = returnValue as Task; if (returnValueTask != null) { // Only return once the task has completed await returnValueTask; } return(Tuple.Create(returnValue, outputs)); } catch (SecurityException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException()); } catch (Exception e) { TraceUtility.TraceUserCodeException(e, this.taskMethod); throw; } finally { OperationContext.DisableAsyncFlow(); if (boundActivity != null) { ((IDisposable)boundActivity).Dispose(); } ServiceModelActivity.Stop(activity); } }