@@ -13,6 +13,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
13
13
{
14
14
public class HttpConnectionMiddleware < TContext >
15
15
{
16
+ private static Action < Exception , object > _completeTcs = CompleteTcs ;
17
+
16
18
private static long _lastFrameConnectionId = long . MinValue ;
17
19
18
20
private readonly IList < IConnectionAdapter > _connectionAdapters ;
@@ -67,30 +69,40 @@ public Task OnConnectionAsync(ConnectionContext connectionContext)
67
69
var processingTask = connection . StartRequestProcessing ( _application ) ;
68
70
69
71
var inputTcs = new TaskCompletionSource < object > ( ) ;
72
+ var outputTcs = new TaskCompletionSource < object > ( ) ;
70
73
71
- // Abort the frame when the transport writer completes
72
- connectionContext . Transport . Input . OnWriterCompleted ( ( error , state ) =>
73
- {
74
- var tcs = ( TaskCompletionSource < object > ) state ;
75
-
76
- if ( error != null )
77
- {
78
- tcs . TrySetException ( error ) ;
79
- }
80
- else
81
- {
82
- tcs . TrySetResult ( null ) ;
83
- }
84
- } ,
85
- inputTcs ) ;
74
+ // The reason we don't fire events directly from these callbacks is because it seems
75
+ // like the transport callbacks root the state object (even after it fires)
76
+ connectionContext . Transport . Input . OnWriterCompleted ( _completeTcs , inputTcs ) ;
77
+ connectionContext . Transport . Output . OnReaderCompleted ( _completeTcs , outputTcs ) ;
86
78
87
79
inputTcs . Task . ContinueWith ( ( task , state ) =>
88
80
{
89
81
( ( FrameConnection ) state ) . Abort ( task . Exception ? . InnerException ) ;
90
82
} ,
91
83
connection , TaskContinuationOptions . ExecuteSynchronously ) ;
92
84
85
+ outputTcs . Task . ContinueWith ( ( task , state ) =>
86
+ {
87
+ ( ( FrameConnection ) state ) . OnConnectionClosed ( task . Exception ? . InnerException ) ;
88
+ } ,
89
+ connection , TaskContinuationOptions . ExecuteSynchronously ) ;
90
+
93
91
return processingTask ;
94
92
}
93
+
94
+ private static void CompleteTcs ( Exception error , object state )
95
+ {
96
+ var tcs = ( TaskCompletionSource < object > ) state ;
97
+
98
+ if ( error != null )
99
+ {
100
+ tcs . TrySetException ( error ) ;
101
+ }
102
+ else
103
+ {
104
+ tcs . TrySetResult ( null ) ;
105
+ }
106
+ }
95
107
}
96
108
}
0 commit comments