Exemple #1
0
        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);
            }
        }