private async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken) { HttpWebResponse response = null; CancellationTokenRegistration connectCancellation = new CancellationTokenRegistration(); // Any errors from here on out are fatal and this instance will be disposed. try { HttpWebRequest request = CreateAndConfigureRequest(uri); if (Logging.On) { Logging.Associate(Logging.WebSockets, this, request); } connectCancellation = cancellationToken.Register(AbortRequest, request, false); response = await request.GetResponseAsync().SuppressContextFlow() as HttpWebResponse; Contract.Assert(response != null, "Not an HttpWebResponse"); if (Logging.On) { Logging.Associate(Logging.WebSockets, this, response); } string subprotocol = ValidateResponse(request, response); innerWebSocket = WebSocket.CreateClientWebSocket(response.GetResponseStream(), subprotocol, options.ReceiveBufferSize, options.SendBufferSize, options.KeepAliveInterval, false, options.GetOrCreateBuffer()); if (Logging.On) { Logging.Associate(Logging.WebSockets, this, innerWebSocket); } // Change internal state to 'connected' to enable the other methods if (Interlocked.CompareExchange(ref state, connected, connecting) != connecting) { // Aborted/Disposed during connect. throw new ObjectDisposedException(GetType().FullName); } } catch (WebException ex) { ConnectExceptionCleanup(response); WebSocketException wex = new WebSocketException(SR.GetString(SR.net_webstatus_ConnectFailure), ex); if (Logging.On) { Logging.Exception(Logging.WebSockets, this, "ConnectAsync", wex); } throw wex; } catch (Exception ex) { ConnectExceptionCleanup(response); if (Logging.On) { Logging.Exception(Logging.WebSockets, this, "ConnectAsync", ex); } throw; } finally { // We successfully connected (or failed trying), disengage from this token. // Otherwise any timeout/cancellation would apply to the full session. // In the failure case we need to release the reference to HWR. connectCancellation.Dispose(); } }