@@ -45,18 +45,43 @@ public CancelableStream(Stream innerStream, CancellationToken cancellationToken)
45
45
_cancellationToken = cancellationToken ;
46
46
}
47
47
48
- public override void Flush ( ) => _innerStream . Flush ( ) ;
48
+ public override void Flush ( ) =>
49
+ _innerStream . FlushAsync ( _cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
50
+
51
+ public override async Task FlushAsync ( CancellationToken cancellationToken )
52
+ {
53
+ using ( var cancellationTokenSource = CreateCancellationTokenSource ( cancellationToken ) )
54
+ {
55
+ await _innerStream . FlushAsync ( cancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
56
+ }
57
+ }
49
58
50
59
public override int Read ( byte [ ] buffer , int offset , int count ) =>
51
60
_innerStream . ReadAsync ( buffer , offset , count , _cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
52
61
62
+ public override async Task < int > ReadAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
63
+ {
64
+ using ( var cancellationTokenSource = CreateCancellationTokenSource ( cancellationToken ) )
65
+ {
66
+ return await _innerStream . ReadAsync ( buffer , offset , count , cancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
67
+ }
68
+ }
69
+
53
70
public override long Seek ( long offset , SeekOrigin origin ) => _innerStream . Seek ( offset , origin ) ;
54
71
55
72
public override void SetLength ( long value ) => _innerStream . SetLength ( value ) ;
56
73
57
74
public override void Write ( byte [ ] buffer , int offset , int count ) =>
58
75
_innerStream . WriteAsync ( buffer , offset , count , _cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
59
76
77
+ public override async Task WriteAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
78
+ {
79
+ using ( var cancellationTokenSource = CreateCancellationTokenSource ( cancellationToken ) )
80
+ {
81
+ await _innerStream . WriteAsync ( buffer , offset , count , cancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
82
+ }
83
+ }
84
+
60
85
public override bool CanRead => _innerStream . CanRead ;
61
86
62
87
public override bool CanSeek => _innerStream . CanSeek ;
@@ -70,6 +95,46 @@ public override long Position
70
95
get => _innerStream . Position ;
71
96
set => _innerStream . Position = value ;
72
97
}
98
+
99
+ protected override void Dispose ( bool disposing )
100
+ {
101
+ if ( disposing )
102
+ {
103
+ _innerStream . Dispose ( ) ;
104
+ }
105
+ base . Dispose ( disposing ) ;
106
+ }
107
+
108
+ private LinkedCancellationTokenSource CreateCancellationTokenSource ( CancellationToken userCancellationToken )
109
+ {
110
+ return new LinkedCancellationTokenSource ( _cancellationToken , userCancellationToken ) ;
111
+ }
112
+
113
+ private readonly struct LinkedCancellationTokenSource : IDisposable
114
+ {
115
+ private readonly CancellationTokenSource _cancellationTokenSource ;
116
+
117
+ public LinkedCancellationTokenSource ( CancellationToken token1 , CancellationToken token2 )
118
+ {
119
+ if ( token1 . CanBeCanceled && token2 . CanBeCanceled )
120
+ {
121
+ _cancellationTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( token1 , token2 ) ;
122
+ Token = _cancellationTokenSource . Token ;
123
+ }
124
+ else
125
+ {
126
+ _cancellationTokenSource = null ;
127
+ Token = token1 . CanBeCanceled ? token1 : token2 ;
128
+ }
129
+ }
130
+
131
+ public CancellationToken Token { get ; }
132
+
133
+ public void Dispose ( )
134
+ {
135
+ _cancellationTokenSource ? . Dispose ( ) ;
136
+ }
137
+ }
73
138
}
74
139
75
140
internal class LineSeparatedHttpContent : HttpContent
@@ -107,24 +172,18 @@ protected override bool TryComputeLength(out long length)
107
172
}
108
173
}
109
174
110
- internal class PeekableStreamReader : StreamReader
175
+ internal class PeekableStreamReader : TextReader
111
176
{
112
- private Queue < string > _buffer ;
177
+ private readonly Queue < string > _buffer ;
178
+ private readonly StreamReader _inner ;
113
179
114
- public PeekableStreamReader ( Stream stream ) : base ( stream )
180
+ public PeekableStreamReader ( Stream stream )
115
181
{
116
182
_buffer = new Queue < string > ( ) ;
183
+ _inner = new StreamReader ( stream ) ;
117
184
}
118
185
119
- public override string ReadLine ( )
120
- {
121
- if ( _buffer . Count > 0 )
122
- {
123
- return _buffer . Dequeue ( ) ;
124
- }
125
-
126
- return base . ReadLine ( ) ;
127
- }
186
+ public override string ReadLine ( ) => throw new NotImplementedException ( ) ;
128
187
129
188
public override Task < string > ReadLineAsync ( )
130
189
{
@@ -133,7 +192,7 @@ public override Task<string> ReadLineAsync()
133
192
return Task . FromResult ( _buffer . Dequeue ( ) ) ;
134
193
}
135
194
136
- return base . ReadLineAsync ( ) ;
195
+ return _inner . ReadLineAsync ( ) ;
137
196
}
138
197
139
198
public async Task < string > PeekLineAsync ( )
@@ -156,6 +215,15 @@ public async Task<string> PeekLineAsync()
156
215
public override string ReadToEnd ( ) => throw new NotImplementedException ( ) ;
157
216
158
217
public override Task < string > ReadToEndAsync ( ) => throw new NotImplementedException ( ) ;
218
+
219
+ protected override void Dispose ( bool disposing )
220
+ {
221
+ if ( disposing )
222
+ {
223
+ _inner . Dispose ( ) ;
224
+ }
225
+ base . Dispose ( disposing ) ;
226
+ }
159
227
}
160
228
}
161
229
}
0 commit comments