@@ -103,12 +103,10 @@ namespace Discord | |||||
finally { _stateLock.Release(); } | finally { _stateLock.Release(); } | ||||
}); | }); | ||||
} | } | ||||
public virtual async Task StopAsync() | |||||
public virtual Task StopAsync() | |||||
{ | { | ||||
Cancel(); | Cancel(); | ||||
var task = _task; | |||||
if (task != null) | |||||
await task.ConfigureAwait(false); | |||||
return Task.CompletedTask; | |||||
} | } | ||||
private async Task ConnectAsync(CancellationTokenSource reconnectCancelToken) | private async Task ConnectAsync(CancellationTokenSource reconnectCancelToken) | ||||
@@ -159,9 +157,9 @@ namespace Discord | |||||
await _onDisconnecting(ex).ConfigureAwait(false); | await _onDisconnecting(ex).ConfigureAwait(false); | ||||
await _logger.InfoAsync("Disconnected").ConfigureAwait(false); | |||||
State = ConnectionState.Disconnected; | |||||
await _disconnectedEvent.InvokeAsync(ex, isReconnecting).ConfigureAwait(false); | await _disconnectedEvent.InvokeAsync(ex, isReconnecting).ConfigureAwait(false); | ||||
State = ConnectionState.Disconnected; | |||||
await _logger.InfoAsync("Disconnected").ConfigureAwait(false); | |||||
} | } | ||||
public async Task CompleteAsync() | public async Task CompleteAsync() | ||||
@@ -207,7 +207,8 @@ namespace Discord.WebSocket | |||||
await heartbeatTask.ConfigureAwait(false); | await heartbeatTask.ConfigureAwait(false); | ||||
_heartbeatTask = null; | _heartbeatTask = null; | ||||
while (_heartbeatTimes.TryDequeue(out long time)) { } | |||||
// Check if hearbeatTimes is not empty before dequeuing. TryDequeue can cause blocking. | |||||
if (!_heartbeatTimes.IsEmpty) while (_heartbeatTimes.TryDequeue(out long time)) { } | |||||
_lastMessageTime = 0; | _lastMessageTime = 0; | ||||
await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false); | await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false); | ||||
@@ -117,6 +117,14 @@ namespace Discord.Net.Udp | |||||
while (!cancelToken.IsCancellationRequested) | while (!cancelToken.IsCancellationRequested) | ||||
{ | { | ||||
var receiveTask = _udp.ReceiveAsync(); | var receiveTask = _udp.ReceiveAsync(); | ||||
_ = receiveTask.ContinueWith((recieveResult) => | |||||
{ | |||||
//observe the exception as to not recieve as unhandled exception | |||||
_ = recieveResult.Exception; | |||||
}, TaskContinuationOptions.OnlyOnFaulted); | |||||
var task = await Task.WhenAny(closeTask, receiveTask).ConfigureAwait(false); | var task = await Task.WhenAny(closeTask, receiveTask).ConfigureAwait(false); | ||||
if (task == closeTask) | if (task == closeTask) | ||||
break; | break; | ||||