private void OpenConnection(Connection connection, string data, Action initializeCallback, Action<Exception> errorCallback) { // If we're reconnecting add /connect to the url bool reconnecting = initializeCallback == null; var url = (reconnecting ? connection.Url : connection.Url + "connect") + GetReceiveQueryString(connection, data); Action<HttpWebRequest> prepareRequest = PrepareRequest(connection); HttpHelper.GetAsync(url, request => { prepareRequest(request); request.Accept = "text/event-stream"; }).ContinueWith(task => { if (task.IsFaulted) { var exception = task.Exception.GetBaseException(); if (!IsRequestAborted(exception)) { if (errorCallback != null && Interlocked.Exchange(ref _initializedCalled, 1) == 0) { errorCallback(exception); } else if (reconnecting) { // Only raise the error event if we failed to reconnect connection.OnError(exception); } } if (reconnecting) { // Retry Reconnect(connection, data); return; } } else { // Get the reseponse stream and read it for messages var response = task.Result; var stream = response.GetResponseStream(); var reader = new AsyncStreamReader(stream, connection, () => { if (Interlocked.CompareExchange(ref _initializedCalled, 1, 0) == 0) { initializeCallback(); } }, () => { response.Close(); Reconnect(connection, data); }); if (reconnecting) { // Raise the reconnect event if the connection comes back up connection.OnReconnected(); } reader.StartReading(); // Set the reader for this connection connection.Items[ReaderKey] = reader; } }); if (initializeCallback != null) { TaskAsyncHelper.Delay(ConnectionTimeout).Then(() => { if (Interlocked.CompareExchange(ref _initializedCalled, 1, 0) == 0) { // Stop the connection Stop(connection); // Connection timeout occured errorCallback(new TimeoutException()); } }); } }