Exemple #1
0
        public async Task DisconnectAsync()
        {
            if (_runTask == null)
            {
                return;
            }

            await TaskUtilities.SwitchToBackgroundThread();

            // We may get MessageTransportException from any concurrent SendAsync or ReceiveAsync when the host
            // drops connection after we request it to do so. To ensure that those don't bubble up to the
            // client, cancel this token to indicate that we're shutting down the host - SendAsync and
            // ReceiveAsync will take care of wrapping any WSE into OperationCanceledException.
            _cts.Cancel();
            var token = await _disconnectLock.WaitAsync();

            if (!token.IsSet)
            {
                try {
                    // Don't use _cts, since it's already cancelled. We want to try to send this message in
                    // any case, and we'll catch MessageTransportException if no-one is on the other end anymore.
                    await _transport.CloseAsync();

                    token.Set();
                } catch (OperationCanceledException) {
                } catch (MessageTransportException) {
                } finally {
                    token.Reset();
                }
            }

            try {
                if (_runTask.Status == TaskStatus.Running)
                {
                    await _runTask;
                }
            } catch (OperationCanceledException) {
                // Expected during disconnect.
            } catch (MessageTransportException) {
                // Possible and valid during disconnect.
            }
        }