private void OpenConnection(Connection connection, string data, Action initializeCallback, Action<Exception> errorCallback) { // If we're reconnecting add /connect to the url bool reconnect = initializeCallback == null; var url = (reconnect ? 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) && Interlocked.CompareExchange(ref connection._initializedCalled, 0, 0) == 0) { if (errorCallback != null) { errorCallback(exception); } else { // Raise the error event if we failed to reconnect connection.OnError(exception); } } } else { // Get the reseponse stream and read it for messages var stream = task.Result.GetResponseStream(); var reader = new AsyncStreamReader(stream, connection, () => { if (Interlocked.CompareExchange(ref connection._initializedCalled, 1, 0) == 0) { initializeCallback(); } }, () => { // Wait for a bit before reconnecting Thread.Sleep(ReconnectDelay); // Now attempt a reconnect OpenConnection(connection, data, initializeCallback: null, errorCallback: null); }); reader.StartReading(); // Set the reader for this connection connection.Items[ReaderKey] = reader; } }); if (initializeCallback != null) { TaskAsyncHelper.Delay(ConnectionTimeout).Then(() => { if (Interlocked.CompareExchange(ref connection._initializedCalled, 1, 0) == 0) { // Stop the connection Stop(connection); // Connection timeout occured errorCallback(new TimeoutException()); } }); } }