Browse Source

Lazy create RequestServicesFeature DisposeAsync statemachine (#9512)

Ben Adams 6 years ago
parent
commit
bae733151b

+ 0 - 1
src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp3.0.cs

@@ -249,7 +249,6 @@ namespace Microsoft.AspNetCore.Http.Features
         public RequestServicesFeature(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory scopeFactory) { }
         public System.IServiceProvider RequestServices { get { throw null; } set { } }
         public void Dispose() { }
-        [System.Diagnostics.DebuggerStepThroughAttribute]
         public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
     }
     public partial class ResponseBodyPipeFeature : Microsoft.AspNetCore.Http.Features.IResponseBodyPipeFeature

+ 18 - 2
src/Http/Http/src/Features/RequestServicesFeature.cs

@@ -42,12 +42,19 @@ namespace Microsoft.AspNetCore.Http.Features
             }
         }
 
-        public async ValueTask DisposeAsync()
+        public ValueTask DisposeAsync()
         {
             switch (_scope)
             {
                 case IAsyncDisposable asyncDisposable:
-                    await asyncDisposable.DisposeAsync();
+                    var vt = asyncDisposable.DisposeAsync();
+                    if (!vt.IsCompletedSuccessfully)
+                    {
+                        return Awaited(this, vt);
+                    }
+                    // If its a IValueTaskSource backed ValueTask,
+                    // inform it its result has been read so it can reset
+                    vt.GetAwaiter().GetResult();
                     break;
                 case IDisposable disposable:
                     disposable.Dispose();
@@ -56,6 +63,15 @@ namespace Microsoft.AspNetCore.Http.Features
 
             _scope = null;
             _requestServices = null;
+
+            return default;
+
+            static async ValueTask Awaited(RequestServicesFeature servicesFeature, ValueTask vt)
+            {
+                await vt;
+                servicesFeature._scope = null;
+                servicesFeature._requestServices = null;
+            }
         }
 
         public void Dispose()