Exemplo n.º 1
0
        private Exception ConvertExceptionForFaultedTask(Task task)
        {
            var exception = task.Exception.InnerException;

            //bool callFaulted;
            if (exception is SecurityException)
            {
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Warning);
                exception = DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
            }
            else if (exception is FaultException)
            {
                //callFaulted = true;
            }
            else
            {
                TraceUtility.TraceUserCodeException(exception, TaskMethod);
            }
            //AsyncMethodInvoker.StopOperationInvokeTrace(true, callFaulted, TaskMethod.Name);
            //AsyncMethodInvoker.StopOperationInvokePerformanceCounters(true, callFaulted, TaskMethod.Name);

            return(exception);
        }
Exemplo n.º 2
0
        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            if (instance == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SFxNoServiceObject));
            }

            object returnVal = null;

            //bool callFailed = true;
            //bool callFaulted = false;
            //ServiceModelActivity activity = null;
            //Activity boundOperation = null;

            try
            {
                //AsyncMethodInvoker.GetActivityInfo(ref activity, ref boundOperation);

                Task <Tuple <object, object[]> > invokeTask = result as Task <Tuple <object, object[]> >;

                if (invokeTask == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.SFxInvalidCallbackIAsyncResult);
                }

                AggregateException       ae    = null;
                Tuple <object, object[]> tuple = null;
                Task task = null;

                if (invokeTask.IsFaulted)
                {
                    Fx.Assert(invokeTask.Exception != null, "Task.IsFaulted guarantees non-null exception.");
                    ae = invokeTask.Exception;
                }
                else
                {
                    Fx.Assert(invokeTask.IsCompleted, "Task.Result is expected to be completed");

                    tuple = invokeTask.Result;
                    task  = tuple.Item1 as Task;

                    if (task == null)
                    {
                        outputs = tuple.Item2;
                        return(null);
                    }

                    if (task.IsFaulted)
                    {
                        Fx.Assert(task.Exception != null, "Task.IsFaulted guarantees non-null exception.");
                        ae = task.Exception;
                    }
                }

                if (ae != null && ae.InnerException != null)
                {
                    if (ae.InnerException is FaultException)
                    {
                        // If invokeTask.IsFaulted we produce the 'callFaulted' behavior below.
                        // Any other exception will retain 'callFailed' behavior.
                        //callFaulted = true;
                        //callFailed = false;
                    }

                    if (ae.InnerException is SecurityException)
                    {
                        DiagnosticUtility.TraceHandledException(ae.InnerException, TraceEventType.Warning);
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
                    }

                    invokeTask.GetAwaiter().GetResult();
                }

                // Task cancellation without an exception indicates failure but we have no
                // additional information to provide.  Accessing Task.Result will throw a
                // TaskCanceledException.   For consistency between void Tasks and Task<T>,
                // we detect and throw here.
                if (task.IsCanceled)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TaskCanceledException(task));
                }

                outputs = tuple.Item2;

                returnVal = isGenericTask ? taskTResultGetMethod.Invoke(task, Type.EmptyTypes) : null;
                //callFailed = false;

                return(returnVal);
            }
            finally
            {
                //if (boundOperation != null)
                //{
                //    ((IDisposable)boundOperation).Dispose();
                //}

                //ServiceModelActivity.Stop(activity);
                //AsyncMethodInvoker.StopOperationInvokeTrace(callFailed, callFaulted, TaskMethod.Name);
                //AsyncMethodInvoker.StopOperationInvokePerformanceCounters(callFailed, callFaulted, TaskMethod.Name);
            }
        }
Exemplo n.º 3
0
        private async Task <Tuple <object, object[]> > InvokeAsync(object instance, object[] inputs)
        {
            EnsureIsInitialized();

            if (instance == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SFxNoServiceObject));
            }

            if (inputs == null)
            {
                if (inputParameterCount > 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxInputParametersToServiceNull, inputParameterCount)));
                }
            }
            else if (inputs.Length != inputParameterCount)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxInputParametersToServiceInvalid, inputParameterCount, inputs.Length)));
            }

            object[] outputs = EmptyArray <object> .Allocate(outputParameterCount);

            //AsyncMethodInvoker.StartOperationInvokePerformanceCounters(taskMethod.Name);

            object returnValue;
            bool   callFailed  = true;
            bool   callFaulted = false;

            //ServiceModelActivity activity = null;
            //Activity boundActivity = null;

            try
            {
                //AsyncMethodInvoker.CreateActivityInfo(ref activity, ref boundActivity);
                //AsyncMethodInvoker.StartOperationInvokeTrace(taskMethod.Name);

                //if (DiagnosticUtility.ShouldUseActivity)
                //{
                //    string activityName = SR.Format(SR.ActivityExecuteMethod, taskMethod.DeclaringType.FullName, taskMethod.Name);
                //    ServiceModelActivity.Start(activity, activityName, ActivityType.ExecuteUserCode);
                //}

                returnValue = 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;
                }

                callFailed = false;

                return(Tuple.Create(returnValue, outputs));
            }
            catch (SecurityException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
            }
            catch (FaultException)
            {
                callFaulted = true;
                throw;
            }
            catch (Exception e)
            {
                TraceUtility.TraceUserCodeException(e, taskMethod);
                throw;
            }
            finally
            {
                //if (boundActivity != null)
                //{
                //    ((IDisposable)boundActivity).Dispose();
                //}

                //ServiceModelActivity.Stop(activity);

                // Any exception above means InvokeEnd will not be called, so complete it here.
                if (callFailed || callFaulted)
                {
                    //AsyncMethodInvoker.StopOperationInvokeTrace(callFailed, callFaulted, TaskMethod.Name);
                    //AsyncMethodInvoker.StopOperationInvokePerformanceCounters(callFailed, callFaulted, TaskMethod.Name);
                }
            }
        }
Exemplo n.º 4
0
        public async ValueTask <(object returnValue, object[] outputs)> InvokeAsync(object instance, object[] inputs)
        {
            if (instance == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SFxNoServiceObject));
            }

            object returnVal = null;

            object[] outputs = null;
            //bool callFailed = true;
            //bool callFaulted = false;
            //ServiceModelActivity activity = null;
            //Activity boundOperation = null;

            try
            {
                //AsyncMethodInvoker.GetActivityInfo(ref activity, ref boundOperation);

                // This code would benefith from a rewrite to call TaskHelpers.ToApmEnd<Tuple<object, object[]>>
                // When doing so make sure there is enought test coverage se PR comment at link below for a good starting point
                // https://github.com/CoreWCF/CoreWCF/pull/54/files/8db6ff9ad6940a1056363defd1f6449adee56e1a#r333826132
                var tupleResult = await InvokeAsyncCore(instance, inputs);

                AggregateException ae = null;
                Task task             = null;

                task = tupleResult.returnValue as Task;

                if (task == null)
                {
                    outputs = tupleResult.outputs;
                    return(null, outputs);
                }

                if (task.IsFaulted)
                {
                    Fx.Assert(task.Exception != null, "Task.IsFaulted guarantees non-null exception.");
                    ae = task.Exception;
                }

                if (ae != null && ae.InnerException != null)
                {
                    if (ae.InnerException is FaultException)
                    {
                        // If invokeTask.IsFaulted we produce the 'callFaulted' behavior below.
                        // Any other exception will retain 'callFailed' behavior.
                        //callFaulted = true;
                        //callFailed = false;
                    }

                    if (ae.InnerException is SecurityException)
                    {
                        DiagnosticUtility.TraceHandledException(ae.InnerException, TraceEventType.Warning);
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
                    }

                    // Rethrow inner exception as is
                    ExceptionDispatchInfo.Capture(ae.InnerException).Throw();
                }

                // Task cancellation without an exception indicates failure but we have no
                // additional information to provide.  Accessing Task.Result will throw a
                // TaskCanceledException.   For consistency between void Tasks and Task<T>,
                // we detect and throw here.
                if (task.IsCanceled)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TaskCanceledException(task));
                }

                outputs = tupleResult.outputs;

                returnVal = _isGenericTask ? _taskTResultGetMethod.Invoke(task, Type.EmptyTypes) : null;
                //callFailed = false;

                return(returnVal, outputs);
            }
            finally
            {
                //if (boundOperation != null)
                //{
                //    ((IDisposable)boundOperation).Dispose();
                //}

                //ServiceModelActivity.Stop(activity);
                //AsyncMethodInvoker.StopOperationInvokeTrace(callFailed, callFaulted, TaskMethod.Name);
                //AsyncMethodInvoker.StopOperationInvokePerformanceCounters(callFailed, callFaulted, TaskMethod.Name);
            }
        }