Lazy create ResourceInvoker.InvokeAsync statemachine
This commit is contained in:
parent
7a4400e3b2
commit
fe6907616b
|
|
@ -57,46 +57,139 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
_cursor = new FilterCursor(filters);
|
_cursor = new FilterCursor(filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task InvokeAsync()
|
public virtual Task InvokeAsync()
|
||||||
{
|
{
|
||||||
|
if (_diagnosticListener.IsEnabled() || _logger.IsEnabled(LogLevel.Information))
|
||||||
|
{
|
||||||
|
return Logged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_actionContextAccessor.ActionContext = _actionContext;
|
||||||
|
var scope = _logger.ActionScope(_actionContext.ActionDescriptor);
|
||||||
|
|
||||||
|
Exception invokeException = null;
|
||||||
|
Task task = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_actionContextAccessor.ActionContext = _actionContext;
|
task = InvokeFilterPipelineAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
invokeException = ex;
|
||||||
|
}
|
||||||
|
|
||||||
_diagnosticListener.BeforeAction(
|
if (invokeException != null)
|
||||||
_actionContext.ActionDescriptor,
|
{
|
||||||
_actionContext.HttpContext,
|
return Awaited(this, Task.FromException(invokeException), scope);
|
||||||
_actionContext.RouteData);
|
}
|
||||||
|
|
||||||
using (_logger.ActionScope(_actionContext.ActionDescriptor))
|
Debug.Assert(task != null);
|
||||||
|
if (!task.IsCompletedSuccessfully)
|
||||||
|
{
|
||||||
|
return Awaited(this, task, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception releaseException = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ReleaseResources();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
releaseException = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception scopeException = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scope.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
scopeException = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (releaseException == null && scopeException == null)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
else if (releaseException != null && scopeException != null)
|
||||||
|
{
|
||||||
|
return Task.FromException(new AggregateException(releaseException, scopeException));
|
||||||
|
}
|
||||||
|
else if (releaseException != null)
|
||||||
|
{
|
||||||
|
return Task.FromException(releaseException);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Task.FromException(scopeException);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task Awaited(ResourceInvoker invoker, Task task, IDisposable scope)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger.ExecutingAction(_actionContext.ActionDescriptor);
|
|
||||||
|
|
||||||
_logger.AuthorizationFiltersExecutionPlan(_filters);
|
|
||||||
_logger.ResourceFiltersExecutionPlan(_filters);
|
|
||||||
_logger.ActionFiltersExecutionPlan(_filters);
|
|
||||||
_logger.ExceptionFiltersExecutionPlan(_filters);
|
|
||||||
_logger.ResultFiltersExecutionPlan(_filters);
|
|
||||||
|
|
||||||
var stopwatch = ValueStopwatch.StartNew();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await InvokeFilterPipelineAsync();
|
await task;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ReleaseResources();
|
invoker.ReleaseResources();
|
||||||
_logger.ExecutedAction(_actionContext.ActionDescriptor, stopwatch.GetElapsedTime());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
scope.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
|
static async Task Logged(ResourceInvoker invoker)
|
||||||
{
|
{
|
||||||
_diagnosticListener.AfterAction(
|
var actionContext = invoker._actionContext;
|
||||||
_actionContext.ActionDescriptor,
|
invoker._actionContextAccessor.ActionContext = actionContext;
|
||||||
_actionContext.HttpContext,
|
|
||||||
_actionContext.RouteData);
|
try
|
||||||
|
{
|
||||||
|
var logger = invoker._logger;
|
||||||
|
|
||||||
|
invoker._diagnosticListener.BeforeAction(
|
||||||
|
actionContext.ActionDescriptor,
|
||||||
|
actionContext.HttpContext,
|
||||||
|
actionContext.RouteData);
|
||||||
|
|
||||||
|
using (logger.ActionScope(actionContext.ActionDescriptor))
|
||||||
|
{
|
||||||
|
logger.ExecutingAction(actionContext.ActionDescriptor);
|
||||||
|
|
||||||
|
var filters = invoker._filters;
|
||||||
|
logger.AuthorizationFiltersExecutionPlan(filters);
|
||||||
|
logger.ResourceFiltersExecutionPlan(filters);
|
||||||
|
logger.ActionFiltersExecutionPlan(filters);
|
||||||
|
logger.ExceptionFiltersExecutionPlan(filters);
|
||||||
|
logger.ResultFiltersExecutionPlan(filters);
|
||||||
|
|
||||||
|
var stopwatch = ValueStopwatch.StartNew();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await invoker.InvokeFilterPipelineAsync();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
invoker.ReleaseResources();
|
||||||
|
logger.ExecutedAction(actionContext.ActionDescriptor, stopwatch.GetElapsedTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
invoker._diagnosticListener.AfterAction(
|
||||||
|
actionContext.ActionDescriptor,
|
||||||
|
actionContext.HttpContext,
|
||||||
|
actionContext.RouteData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue