private static async Task <HttpResponseMessage> SendAsyncWithRetry(HttpRequestFactoryDelegate requestFactory, CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { // Call SendAsync with a new request object each time, since it's invalid to send the same request object twice. var response = await httpClient.SendAsync(requestFactory(), cancellationToken); if (response.IsSuccessStatusCode) { return(response); } else if (response.StatusCode != HttpStatusCode.BadGateway && response.StatusCode != HttpStatusCode.RequestTimeout && response.StatusCode != HttpStatusCode.ServiceUnavailable) { return(response); } } catch (WebException webException) { if (webException.Status != WebExceptionStatus.ReceiveFailure && webException.Status != WebExceptionStatus.ConnectFailure && webException.Status != WebExceptionStatus.KeepAliveFailure) { throw webException; } } } ; return(null); }
private static async Task <APIResult> CallMediaWikiAPI(string options, CancellationToken cancellationToken) { // Post the request to the MediaWiki API endpoint. var uri = string.Format("{0}api.php", baseURI, options); HttpRequestFactoryDelegate requestFactory = () => { var request = new HttpRequestMessage(HttpMethod.Post, uri); request.Content = new StringContent(options, Encoding.UTF8, "application/x-www-form-urlencoded"); return(request); }; using (var postResponse = await SendAsyncWithRetry(requestFactory, cancellationToken)) { // Read the response. if (!cancellationToken.IsCancellationRequested && postResponse.IsSuccessStatusCode) { var responseString = await postResponse.Content.ReadAsStringAsync(); var responseDocument = new XmlDocument(); responseDocument.Load(new StringReader(responseString.TrimStart(' ', '\t', '\r', '\n'))); // Check for an API error. var result = new APIResult(); var errorElement = responseDocument.SelectSingleNode("/error"); if (errorElement != null) { // Extract the API error code and description. result.errorCode = errorElement.Attributes["code"].Value; result.errorDescription = errorElement.Attributes["info"].Value; result.bSuccess = false; } else { // If the API call succeeded, extract the resulting XML tree. result.resultXML = responseDocument["api"]; result.bSuccess = true; } return(result); } else { // If the HTTP request failed, setup an unsuccesful result struct. var result = new APIResult(); result.resultXML = null; result.errorCode = postResponse.StatusCode.ToString(); result.errorDescription = postResponse.ReasonPhrase; result.bSuccess = false; return(result); } } }