GetXmlDocumentWithRetries ( String sUrl, HttpStatusCode [] aeHttpStatusCodesToFailImmediately, RequestStatistics oRequestStatistics ) { Debug.Assert(!String.IsNullOrEmpty(sUrl)); Debug.Assert(oRequestStatistics != null); AssertValid(); Stream oStream = null; try { oStream = HttpSocialNetworkUtil.GetHttpWebResponseStreamWithRetries( sUrl, aeHttpStatusCodesToFailImmediately, oRequestStatistics, UserAgent, HttpWebRequestTimeoutMs, new ReportProgressHandler(this.ReportProgress), new CheckCancellationPendingHandler( this.CheckCancellationPending) ); XmlDocument oXmlDocument = new XmlDocument(); oXmlDocument.Load(oStream); return(oXmlDocument); } finally { if (oStream != null) { oStream.Close(); } } }
GetTwitterResponseAsString ( String url, RequestStatistics requestStatistics, ReportProgressHandler reportProgressHandler, CheckCancellationPendingHandler checkCancellationPendingHandler ) { Debug.Assert(!String.IsNullOrEmpty(url)); Debug.Assert(requestStatistics != null); AssertValid(); Int32 iRateLimitPauses = 0; Int32 iInvalidJsonRepeats = 0; const Int32 MaximumInvalidJsonRepeats = 3; while (true) { // Add the required authorization information to the URL. // // Note: Don't do this outside the while (true) loop. The // authorization information includes a timestamp that will // probably expire if the code within the catch block pauses. oAuthTwitter oAuthTwitter = new oAuthTwitter( m_UserAgent, m_TimeoutMs); oAuthTwitter.Token = m_TwitterAccessToken; oAuthTwitter.TokenSecret = m_TwitterAccessTokenSecret; String sAuthorizedUrl, sAuthorizedPostData; oAuthTwitter.ConstructAuthWebRequest(oAuthTwitter.Method.GET, url, String.Empty, out sAuthorizedUrl, out sAuthorizedPostData); url = sAuthorizedUrl; Stream oStream = null; try { oStream = HttpSocialNetworkUtil.GetHttpWebResponseStreamWithRetries( url, HttpStatusCodesToFailImmediately, requestStatistics, m_UserAgent, m_TimeoutMs, reportProgressHandler, checkCancellationPendingHandler); return(GetTwitterResponseAsString(oStream)); } catch (InvalidJsonException oInvalidJsonException) { iInvalidJsonRepeats++; if (iInvalidJsonRepeats > MaximumInvalidJsonRepeats) { throw oInvalidJsonException; } HttpSocialNetworkUtil.ReportProgress(reportProgressHandler, "Received invalid JSON from Twitter. Trying again." ); } catch (WebException oWebException) { if ( !WebExceptionIsDueToRateLimit(oWebException) || iRateLimitPauses > 0 ) { throw; } // Twitter rate limits have kicked in. Pause and try again. iRateLimitPauses++; Int32 iRateLimitPauseMs = GetRateLimitPauseMs(oWebException); DateTime oWakeUpTime = DateTime.Now.AddMilliseconds( iRateLimitPauseMs); HttpSocialNetworkUtil.ReportProgress(reportProgressHandler, "Reached Twitter rate limits. Pausing until {0}." , oWakeUpTime.ToLongTimeString() ); // Don't pause in one large interval, which would prevent // cancellation. const Int32 SleepCycleDurationMs = 1000; Int32 iSleepCycles = (Int32)Math.Ceiling( (Double)iRateLimitPauseMs / SleepCycleDurationMs); for (Int32 i = 0; i < iSleepCycles; i++) { if (checkCancellationPendingHandler != null) { checkCancellationPendingHandler(); } System.Threading.Thread.Sleep(SleepCycleDurationMs); } } finally { if (oStream != null) { oStream.Close(); } } } }