/// <summary> /// Callback method called when the "Download" method returns from an HTTPWebRequest. /// </summary> /// <param name="result">The result of the asynchronous operation.</param> private void ResponseCallback(IAsyncResult result) { RequestState state = result.AsyncState as RequestState; Feed parentFeed = state.Argument as Feed; if (null != parentFeed) { HttpWebRequest request = state.Request as HttpWebRequest; // Progress only if this download has not been timed out. if (null != request) { // Retrieve response. try { using (HttpWebResponse response = request.EndGetResponse(result) as HttpWebResponse) { if (null != response && response.StatusCode == HttpStatusCode.OK) { using (XmlReader reader = XmlReader.Create(response.GetResponseStream())) { // Collection to store all articles Collection <Article> parsedArticles = _parser.ParseItems(reader, parentFeed); // Raise event for a single feed downloaded. if (null != SingleDownloadFinished) { SingleDownloadFinished(this, new SingleDownloadFinishedEventArgs(parentFeed, parsedArticles)); } // Add to all downloads dictionary and raise AllDownloadsFinished if all async requests have finished. Downloads.Add(parentFeed, parsedArticles); CheckIfDone(); } } } } catch (WebException we) { if (we.Status == WebExceptionStatus.RequestCanceled) { // The web request was timed out. Let debug know it failed. System.Diagnostics.Debug.WriteLine("ERROR: Feed \"" + parentFeed.FeedTitle + "\" was timed out."); CheckIfDone(); return; } else if (we.Message == "The remote server returned an error: NotFound.") { // The web site did not respond. This means one of two things: Either the web site is bad, or you have no internet. // If error code NotFound is received, then there is no connection. Throw the exception. if ((we.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound) { // WebTools throws an exception if without connection. Warn the user. CheckIfDone(); if (!IsDownloading) { Deployment.Current.Dispatcher.BeginInvoke(() => { MessageBox.Show("FeedCast is unable to reach a connection. Please check your network connectivity."); }); } } // If error code InternalServerError is received, then it is a faulty site. else { System.Diagnostics.Debug.WriteLine("ERROR: Feed \"" + parentFeed.FeedTitle + "\" is faulty."); CheckIfDone(); return; } } else { // Unexpected web exception. throw we; } } } } }
/// <summary> /// Downloads the provided List of Feeds. /// You cannot call download while downloads are in progress. /// </summary> /// <param name="feeds">List of feeds to download.</param> public void Download(IList <Feed> feeds) { // Clear any leftover stored articles/feeds in Downloads and _allRequests. Downloads.Clear(); _allRequests.Clear(); // Set the timer for timeouts if parsing syndication feeds. if (_parser is SynFeedParser) { int timeLimit; if (Settings.InitialLaunchSetting) { timeLimit = 20000; // 20 second limit for initial launch. } else { timeLimit = 7500; // Otherwise, 7.5 second time limit. } TimerCallback tc = new TimerCallback(TimeoutConnections); _timeout = new Timer(tc, this, timeLimit, Timeout.Infinite); } if (null != feeds && feeds.Count > 0) { lock (_lockObject) { _numOfRequests += feeds.Count; } IsDownloading = true; // Download each separate feed. foreach (Feed feed in feeds) { string feedURI = feed.FeedBaseURI; if (null != feedURI) { HttpWebRequest feedRequest = HttpWebRequest.Create(feedURI) as HttpWebRequest; // Check if the application has been set to wifi-only or not. if (WifiOnly) { feedRequest.SetNetworkRequirement(NetworkSelectionCharacteristics.NonCellular); } if (null != feedRequest) { RequestState feedState = new RequestState() { // Change the owner to the parent HTTPWebRequest. Request = feedRequest, // Change the argument to be the current feed to be downloaded. Argument = feed, }; // Begin download. feedRequest.BeginGetResponse(ResponseCallback, feedState); // Keep track of the download. _allRequests.Add(feed, feedRequest); } } } } }