public async Task CloseNetworkConnectionAsync(CancellationToken cancellationToken)
{
// need to yield here to make sure that we don't get any exception synchronously
await Task.Yield();
if (NetEventSource.IsEnabled)
{
NetEventSource.Enter(this);
}
CancellationTokenRegistration cancellationTokenRegistration = new CancellationTokenRegistration();
try
{
if (cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.Register(s_OnCancel, this, false);
}
#if DEBUG
// When using fast path only one outstanding read is permitted. By switching into opaque mode
// via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition)
// caller takes responsibility for enforcing this constraint.
Debug.Assert(Interlocked.Increment(ref _outstandingOperations._writes) == 1,
"Only one outstanding write allowed at any given time.");
#endif
_writeTaskCompletionSource = new TaskCompletionSource<object>();
_writeEventArgs.SetShouldCloseOutput();
if (WriteAsyncFast(_writeEventArgs))
{
await _writeTaskCompletionSource.Task.SuppressContextFlow();
}
}
catch (Exception error)
{
if (!s_CanHandleException(error))
{
throw;
}
// throw OperationCancelledException when canceled by the caller
// otherwise swallow the exception
cancellationToken.ThrowIfCancellationRequested();
}
finally
{
cancellationTokenRegistration.Dispose();
if (NetEventSource.IsEnabled)
{
NetEventSource.Exit(this);
}
}
}