/// <summary> /// Queues given <see cref="AsyncInvocation" /> for execution by <see cref="AsyncJobScheduler" />. /// </summary> /// <param name="asyncInvocation"><see cref="AsyncInvocation" /> to invoke.</param> /// <remarks> /// For performance reasons, the internal execution method utilizes ConfigureAwait(false). /// </remarks> public static void QueueAsyncInvocation(AsyncInvocation asyncInvocation) { if (AbortToken.IsCancellationRequested) { return; } else if (asyncInvocation == null) { throw new NullReferenceException(nameof(asyncInvocation)); } Task.Run(() => ExecuteInvocation(asyncInvocation)); }
void IInterceptor.Intercept(IInvocation invocation) { var returnType = invocation.Method.ReturnType; var builder = AsyncMethodBuilder.TryCreate(returnType); if (builder != null) { var asyncInvocation = new AsyncInvocation(invocation); var stateMachine = new AsyncStateMachine(asyncInvocation, builder, task: this.InterceptAsync(asyncInvocation)); builder.Start(stateMachine); invocation.ReturnValue = builder.Task(); } else { this.Intercept(invocation); } }
private static async Task ExecuteInvocation(AsyncInvocation invocation) { Debug.Assert(invocation != null); if (AbortToken.IsCancellationRequested) { return; } try { await _WorkerSemaphore.WaitAsync().ConfigureAwait(false); await invocation.Invoke().ConfigureAwait(false); } finally { // release semaphore regardless of any invocation errors _WorkerSemaphore.Release(); } }