@@ -237,10 +237,10 @@ public void Start()
237
237
{
238
238
CreateWebSocket ( ) ;
239
239
240
- // kick off message parser and message listener
241
- Task . Run ( MessageTask ) ;
242
- Task . Run ( ReadTask ) ;
243
- }
240
+ // kick off message parser and message listener
241
+ Task . Run ( MessageTask ) ;
242
+ Task . Run ( ReadTask ) ;
243
+ }
244
244
245
245
/// <summary>
246
246
/// Close and dispose of all resources, stops the web socket and shuts it down.
@@ -249,34 +249,38 @@ public void Dispose()
249
249
{
250
250
if ( ! disposed )
251
251
{
252
- disposed = true ;
253
- cancellationTokenSource . Cancel ( ) ;
254
- Task . Run ( async ( ) =>
255
- {
256
- try
257
- {
258
- if ( webSocket . State == WebSocketState . Open )
259
- {
260
- if ( CloseCleanly )
261
- {
262
- await webSocket . CloseAsync ( WebSocketCloseStatus . NormalClosure , "Dispose" , cancellationToken ) ;
263
- }
264
- else
265
- {
266
- await webSocket . CloseOutputAsync ( WebSocketCloseStatus . NormalClosure , "Dispose" , cancellationToken ) ;
267
- }
268
- }
269
- }
270
- catch ( OperationCanceledException )
271
- {
272
- // dont care
273
- }
274
- catch ( Exception ex )
275
- {
276
- Logger . Info ( ex . ToString ( ) ) ;
277
- }
278
- } ) ;
279
- }
252
+ Task . Run ( async ( ) =>
253
+ {
254
+ try
255
+ {
256
+ if ( webSocket . State == WebSocketState . Open )
257
+ {
258
+ if ( CloseCleanly )
259
+ {
260
+ await webSocket . CloseAsync ( WebSocketCloseStatus . NormalClosure ,
261
+ "Dispose" , cancellationToken ) ;
262
+ }
263
+ else
264
+ {
265
+ await webSocket . CloseOutputAsync ( WebSocketCloseStatus . NormalClosure ,
266
+ "Dispose" , cancellationToken ) ;
267
+ }
268
+ }
269
+ disposed = true ;
270
+ }
271
+ catch ( OperationCanceledException )
272
+ {
273
+ // dont care
274
+ }
275
+ catch ( Exception ex )
276
+ {
277
+ Logger . Info ( ex . ToString ( ) ) ;
278
+ }
279
+ cancellationTokenSource . Cancel ( ) ;
280
+ webSocket . Dispose ( ) ;
281
+ messageQueue . CompleteAdding ( ) ;
282
+ } ) ;
283
+ }
280
284
}
281
285
282
286
/// <summary>
@@ -317,7 +321,7 @@ public Task<bool> SendMessageAsync(object message)
317
321
318
322
private void QueueActions ( params Func < IWebSocket , Task > [ ] actions )
319
323
{
320
- if ( actions != null && actions . Length != 0 )
324
+ if ( actions != null && actions . Length != 0 && ! messageQueue . IsAddingCompleted )
321
325
{
322
326
Func < IWebSocket , Task > [ ] actionsCopy = actions ;
323
327
messageQueue . Add ( ( Func < Task > ) ( async ( ) =>
@@ -339,8 +343,8 @@ private void QueueActions(params Func<IWebSocket, Task>[] actions)
339
343
340
344
private void QueueActionsWithNoExceptions ( params Func < IWebSocket , Task > [ ] actions )
341
345
{
342
- if ( actions != null && actions . Length != 0 )
343
- {
346
+ if ( actions != null && actions . Length != 0 && ! messageQueue . IsAddingCompleted )
347
+ {
344
348
Func < IWebSocket , Task > [ ] actionsCopy = actions ;
345
349
messageQueue . Add ( ( Func < Task > ) ( async ( ) =>
346
350
{
@@ -384,7 +388,6 @@ private async Task InvokeDisconnected(IWebSocket socket)
384
388
private async Task ReadTask ( )
385
389
{
386
390
ArraySegment < byte > receiveBuffer = new ArraySegment < byte > ( new byte [ receiveChunkSize ] ) ;
387
- TimeSpan keepAlive = webSocket . KeepAliveInterval ;
388
391
MemoryStream stream = new MemoryStream ( ) ;
389
392
WebSocketReceiveResult result ;
390
393
bool wasConnected = false ;
@@ -411,7 +414,7 @@ private async Task ReadTask()
411
414
// for lists, etc.
412
415
QueueActionsWithNoExceptions ( InvokeConnected ) ;
413
416
414
- while ( webSocket . State == WebSocketState . Open )
417
+ while ( webSocket . State == WebSocketState . Open && ! disposed )
415
418
{
416
419
do
417
420
{
@@ -420,7 +423,8 @@ private async Task ReadTask()
420
423
{
421
424
if ( result . MessageType == WebSocketMessageType . Close )
422
425
{
423
- await webSocket . CloseAsync ( WebSocketCloseStatus . NormalClosure , string . Empty , cancellationToken ) ;
426
+ await webSocket . CloseAsync ( WebSocketCloseStatus . NormalClosure ,
427
+ string . Empty , new CancellationToken ( ) ) ; // if it's closing, then let it complete
424
428
QueueActions ( InvokeDisconnected ) ;
425
429
}
426
430
else
@@ -429,8 +433,8 @@ private async Task ReadTask()
429
433
}
430
434
}
431
435
}
432
- while ( result != null && ! result . EndOfMessage ) ;
433
- if ( stream . Length != 0 )
436
+ while ( result != null && ! result . EndOfMessage && ! disposed ) ;
437
+ if ( stream . Length != 0 && ! disposed )
434
438
{
435
439
// if text message and we are handling text messages
436
440
if ( result . MessageType == WebSocketMessageType . Text && OnTextMessage != null )
@@ -450,11 +454,15 @@ private async Task ReadTask()
450
454
}
451
455
}
452
456
}
453
- catch ( OperationCanceledException )
454
- {
455
- // dont care
456
- }
457
- catch ( Exception ex )
457
+ catch ( OperationCanceledException ) // includes TaskCanceledException
458
+ {
459
+ // dont care
460
+ }
461
+ catch ( IOException ex )
462
+ {
463
+ Logger . Info ( ex . ToString ( ) ) ;
464
+ }
465
+ catch ( Exception ex )
458
466
{
459
467
// eat exceptions, most likely a result of a disconnect, either way we will re-create the web socket
460
468
Logger . Info ( ex . ToString ( ) ) ;
@@ -466,7 +474,8 @@ private async Task ReadTask()
466
474
}
467
475
try
468
476
{
469
- webSocket . Dispose ( ) ;
477
+ stream . Close ( ) ;
478
+ webSocket . Dispose ( ) ;
470
479
}
471
480
catch ( Exception ex )
472
481
{
0 commit comments