diff --git a/src/Autofac.Integration.Web/ContainerDisposalModule.cs b/src/Autofac.Integration.Web/ContainerDisposalModule.cs index d76e704..d7263dd 100644 --- a/src/Autofac.Integration.Web/ContainerDisposalModule.cs +++ b/src/Autofac.Integration.Web/ContainerDisposalModule.cs @@ -23,6 +23,7 @@ // OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Threading.Tasks; using System.Web; namespace Autofac.Integration.Web @@ -55,18 +56,35 @@ public void Init(HttpApplication context) if (_containerProviderAccessor == null) throw new InvalidOperationException(ContainerDisposalModuleResources.ApplicationMustImplementAccessor); - context.EndRequest += OnEndRequest; + var wrapper = new EventHandlerTaskAsyncHelper(OnEndRequest); + + context.AddOnEndRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler); } /// /// Dispose of the per-request container. /// - private void OnEndRequest(object sender, EventArgs e) + private Task OnEndRequest(object sender, EventArgs e) { var cp = _containerProviderAccessor.ContainerProvider; if (cp == null) throw new InvalidOperationException(ContainerDisposalModuleResources.ContainerProviderNull); - cp.EndRequestLifetime(); + + var valueTask = cp.EndRequestLifetime(); + + // https://github.com/dotnet/aspnetcore/blob/main/src/Shared/ValueTaskExtensions/ValueTaskExtensions.cs#L13 + + // Try to avoid the allocation from AsTask + if (valueTask.IsCompletedSuccessfully) + { + // Signal consumption to the IValueTaskSource + valueTask.GetAwaiter().GetResult(); + return Task.CompletedTask; + } + else + { + return valueTask.AsTask(); + } } } } diff --git a/src/Autofac.Integration.Web/ContainerProvider.cs b/src/Autofac.Integration.Web/ContainerProvider.cs index 08c0c2b..5fb5497 100644 --- a/src/Autofac.Integration.Web/ContainerProvider.cs +++ b/src/Autofac.Integration.Web/ContainerProvider.cs @@ -23,6 +23,7 @@ // OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Threading.Tasks; using System.Web; using Autofac.Core.Lifetime; @@ -61,11 +62,10 @@ public ContainerProvider(IContainer applicationContainer, Action - public void EndRequestLifetime() + public ValueTask EndRequestLifetime() { var rc = AmbientRequestLifetime; - if (rc != null) - rc.Dispose(); + return rc == null ? default : rc.DisposeAsync(); } /// diff --git a/src/Autofac.Integration.Web/IContainerProvider.cs b/src/Autofac.Integration.Web/IContainerProvider.cs index bdc64a1..66c1a67 100644 --- a/src/Autofac.Integration.Web/IContainerProvider.cs +++ b/src/Autofac.Integration.Web/IContainerProvider.cs @@ -22,6 +22,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. +using System.Threading.Tasks; + namespace Autofac.Integration.Web { /// @@ -34,7 +36,7 @@ public interface IContainerProvider /// Dispose of the current request's container, if it has been /// instantiated. /// - void EndRequestLifetime(); + ValueTask EndRequestLifetime(); /// /// Gets the global, application-wide container.