@@ -20,7 +20,7 @@ public static class AsyncReceiveExtensions
20
20
static Task < bool > s_trueTask = Task . FromResult ( true ) ;
21
21
static Task < bool > s_falseTask = Task . FromResult ( false ) ;
22
22
23
- #region Receiving frames as a multipart message
23
+ #region Receiving frames as a multipart message
24
24
25
25
/// <summary>
26
26
/// Receive a single frame from <paramref name="socket"/>, asynchronously.
@@ -52,9 +52,9 @@ public static async Task<NetMQMessage> ReceiveMultipartMessageAsync(
52
52
return message ;
53
53
}
54
54
55
- #endregion
55
+ #endregion
56
56
57
- #region Receiving a frame as a byte array
57
+ #region Receiving a frame as a byte array
58
58
59
59
/// <summary>
60
60
/// Receive a single frame from <paramref name="socket"/>, asynchronously.
@@ -85,8 +85,12 @@ public static async Task<NetMQMessage> ReceiveMultipartMessageAsync(
85
85
}
86
86
87
87
TaskCompletionSource < ( byte [ ] , bool ) > source = new TaskCompletionSource < ( byte [ ] , bool ) > ( ) ;
88
+
88
89
CancellationTokenRegistration ? registration = null ;
89
- registration = cancellationToken . Register ( PropagateCancel ) ;
90
+ if ( cancellationToken . CanBeCanceled )
91
+ {
92
+ registration = cancellationToken . Register ( PropagateCancel ) ;
93
+ }
90
94
91
95
void Listener ( object sender , NetMQSocketEventArgs args )
92
96
{
@@ -114,9 +118,9 @@ void PropagateCancel()
114
118
return source . Task ;
115
119
}
116
120
117
- #endregion
121
+ #endregion
118
122
119
- #region Receiving a frame as a string
123
+ #region Receiving a frame as a string
120
124
121
125
/// <summary>
122
126
/// Receive a single frame from <paramref name="socket"/>, asynchronously, and decode as a string using <see cref="SendReceiveConstants.DefaultEncoding"/>.
@@ -164,7 +168,12 @@ void PropagateCancel()
164
168
}
165
169
166
170
TaskCompletionSource < ( string , bool ) > source = new TaskCompletionSource < ( string , bool ) > ( ) ;
167
- cancellationToken . Register ( ( ) => source . SetCanceled ( ) ) ;
171
+
172
+ CancellationTokenRegistration ? registration = null ;
173
+ if ( cancellationToken . CanBeCanceled )
174
+ {
175
+ registration = cancellationToken . Register ( PropagateCancel ) ;
176
+ }
168
177
169
178
void Listener ( object sender , NetMQSocketEventArgs args )
170
179
{
@@ -174,28 +183,40 @@ void Listener(object sender, NetMQSocketEventArgs args)
174
183
? msg . GetString ( encoding )
175
184
: string . Empty ;
176
185
bool more = msg . HasMore ;
177
-
178
186
msg . Close ( ) ;
187
+
179
188
socket . ReceiveReady -= Listener ;
180
- source . SetResult ( ( str , more ) ) ;
189
+ registration ? . Dispose ( ) ;
190
+ source . TrySetResult ( ( str , more ) ) ;
181
191
}
182
192
}
183
193
194
+ void PropagateCancel ( )
195
+ {
196
+ socket . ReceiveReady -= Listener ;
197
+ registration ? . Dispose ( ) ;
198
+ source . TrySetCanceled ( ) ;
199
+ }
200
+
184
201
socket . ReceiveReady += Listener ;
185
202
186
203
return source . Task ;
187
204
}
188
205
189
- #endregion
206
+ #endregion
190
207
191
- #region Skipping a message
208
+ #region Skipping a message
192
209
193
210
/// <summary>
194
211
/// Receive a single frame from <paramref name="socket"/>, asynchronously, then ignore its content.
195
212
/// </summary>
196
213
/// <param name="socket">The socket to receive from.</param>
214
+ /// <param name="cancellationToken">The token used to propagate notification that this operation should be canceled.</param>
197
215
/// <returns>Boolean indicate if another frame of the same message follows</returns>
198
- public static Task < bool > SkipFrameAsync ( this NetMQSocket socket )
216
+ public static Task < bool > SkipFrameAsync (
217
+ this NetMQSocket socket ,
218
+ CancellationToken cancellationToken = default ( CancellationToken )
219
+ )
199
220
{
200
221
if ( NetMQRuntime . Current == null )
201
222
throw new InvalidOperationException ( "NetMQRuntime must be created before calling async functions" ) ;
@@ -215,26 +236,41 @@ public static Task<bool> SkipFrameAsync(this NetMQSocket socket)
215
236
216
237
TaskCompletionSource < bool > source = new TaskCompletionSource < bool > ( ) ;
217
238
239
+ CancellationTokenRegistration ? registration = null ;
240
+ if ( cancellationToken . CanBeCanceled )
241
+ {
242
+ registration = cancellationToken . Register ( PropagateCancel ) ;
243
+ }
244
+
218
245
void Listener ( object sender , NetMQSocketEventArgs args )
219
246
{
220
247
if ( socket . TryReceive ( ref msg , TimeSpan . Zero ) )
221
248
{
222
249
bool more = msg . HasMore ;
223
250
msg . Close ( ) ;
251
+
224
252
socket . ReceiveReady -= Listener ;
225
- source . SetResult ( more ) ;
253
+ registration ? . Dispose ( ) ;
254
+ source . TrySetResult ( more ) ;
226
255
}
227
256
}
228
257
258
+ void PropagateCancel ( )
259
+ {
260
+ socket . ReceiveReady -= Listener ;
261
+ registration ? . Dispose ( ) ;
262
+ source . TrySetCanceled ( ) ;
263
+ }
264
+
229
265
socket . ReceiveReady += Listener ;
230
266
231
267
return source . Task ;
232
268
}
233
269
234
270
235
- #endregion
271
+ #endregion
236
272
237
- #region Skipping all frames of a multipart message
273
+ #region Skipping all frames of a multipart message
238
274
239
275
/// <summary>
240
276
/// Receive all frames of the next message from <paramref name="socket"/>, asynchronously, then ignore their contents.
@@ -251,9 +287,9 @@ public static async Task SkipMultipartMessageAsync(this NetMQSocket socket)
251
287
}
252
288
253
289
254
- #endregion
290
+ #endregion
255
291
256
- #region Receiving a routing key
292
+ #region Receiving a routing key
257
293
258
294
/// <summary>
259
295
/// Receive a routing-key from <paramref name="socket"/>, blocking until one arrives.
@@ -268,7 +304,7 @@ public static async Task SkipMultipartMessageAsync(this NetMQSocket socket)
268
304
return ( new RoutingKey ( bytes ) , more ) ;
269
305
}
270
306
271
- #endregion
307
+ #endregion
272
308
}
273
309
}
274
310
0 commit comments