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