예제 #1
0
        public void OnServerException(ServerExceptionContext filterContext)
        {
            Assert.NotNull(filterContext);

            _results.Add(_name);

            if (_handlesException)
            {
                filterContext.ExceptionHandled = true;
            }
        }
            public async Task <object> PerformAsync()
            {
                State state; object data;

                try
                {
                    // Primary loop to handle job filters and background jobs

                    // SHOULD BE: _performingContext = new PerformingContext(_context);
                    _performingContext = new PerformingContext(_context);

                    try
                    {
                        for (state = State.Begin, data = null; state != State.End; JobCancellationToken.ThrowIfCancellationRequested())
                        {
                            // All processing is performed in a tight loop inside the following method.
                            // We'll only get back here sometimes to wait for the next Task to complete.
                            // For performance's sake, we'll only await for really unfinished jobs
                            // (i.e. not constanst/cached/finished ones like Task.FromResult() etc.)
                            await JobFilters(ref state, ref data).ConfigureAwait(false);
                        }
                    }
                    catch (Exception ex)
                    {
                        // This is an exception from pre/post-processing phases.
                        // Though it shouldn't be processed by other job filters,
                        // it still may be handled by exception filters.
                        CoreAsyncBackgroundJobPerformer.HandleJobPerformanceException(ex, JobCancellationToken.ShutdownToken);
                        throw;
                    }

                    if (_performedContext?.Exception != null && !_performedContext.ExceptionHandled)
                    {
                        // This is an exception from job processing phase.
                        // It has been delivered to all job filters, but still unhandled.
                        // Rethrow it here, so it will be picked up by exception filters.
                        ExceptionDispatchInfo.Capture(_performedContext.Exception).Throw();
                    }
                }
                catch (JobAbortedException)
                {
                    // Never intercept JobAbortException, it is supposed for internal use.
                    throw;
                }
                catch (OperationCanceledException) when(JobCancellationToken.ShutdownToken.IsCancellationRequested)
                {
                    // Don't intercept OperationCancelledException after cancellation was requested.
                    throw;
                }
                catch (Exception ex)
                {
                    // Secondary loop to handle exception filters

                    // SHOULD BE: _exceptionContext = new ServerExceptionContext(_context, ex);
                    _exceptionContext = new ServerExceptionContext(_context, ex);

                    for (state = State.Begin, data = null; state != State.End; JobCancellationToken.ThrowIfCancellationRequested())
                    {
                        await ExceptionFilters(ref state, ref data).ConfigureAwait(false);
                    }

                    if (!_exceptionContext.ExceptionHandled)
                    {
                        // None of the exception filters has handled the exception.
                        // We're out of options, so just re-throw it here.
                        ExceptionDispatchInfo.Capture(_exceptionContext.Exception).Throw();
                    }
                }

                return(_performedContext?.Result);
            }