Note that there are some explanatory texts on larger screens.

plurals
  1. POC# Async WebRequests: Odd Results
    primarykey
    data
    text
    <p>I have this little C# console program that's designed to run through a list of URLs and fetch html from the corresponding page. It works to some extent, but I'm having problems with making <code>Async callbacks</code> execute the proper number of times and handle timeouts.</p> <p><strong>Problem:</strong> I'm getting spotty results. Sometimes I run the code and the results are as expected (for example, I give it 7 URLs to look at and it outputs 7 results and 1 complete event), but other times the results make no sense to me (for example, I run 7 URLs and get 2 or 3 complete events or only 6 results with no complete event at all). Could someone explain why this is happening and how to fix it?</p> <p>Results seem to vary even when running the exact same 7 URLs. I guess this is because sometimes a site timeouts out, but my code is designed to handle timeouts gracefully. It's also designed to handle improper URLs. Give it a couple of runs and let me know what you think.</p> <p>This is driving me nuts!</p> <blockquote> <p>It's important that the final solution handles improper URLs, timeouts, and sites that don't exist. An <strong>onComplete</strong> event should trigger once all URLs have been processed.</p> </blockquote> <pre><code>using System; using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; namespace AsyncApp_03 { using System; using System.Net; using System.IO; using System.Text; using System.Threading; class Program { static int _count = 0; static int _invalid = 0; static int _total = 0; static void Main(string[] args) { ArrayList alSites = new ArrayList(); alSites.Add("http://www.google.com"); alSites.Add("adsfsdfsdfsdffd"); alSites.Add("http://wwww.fjasjfejlajfl"); alSites.Add("http://mundocinema.com/noticias/the-a-team-2/4237"); alSites.Add("http://www.spmb.or.id/?p=64"); alSites.Add("http://gprs-edge.ru/?p=3"); alSites.Add("http://blog.tmu.edu.tw/MT/mt-comments.pl?entry_id=3141"); _total = alSites.Count; ScanSites(alSites); Console.Read(); } private static void ScanSites(ArrayList sites) { foreach (string uriString in sites) { try { WebRequest request = HttpWebRequest.Create(uriString); request.Method = "GET"; object data = new object(); //container for our "Stuff" // RequestState is a custom class to pass info to the callback RequestState state = new RequestState(request, data, uriString); IAsyncResult result = request.BeginGetResponse(new AsyncCallback(UpdateItem), state); //Register the timeout callback ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), state, (5 * 1000), true); } catch { Console.WriteLine("Invalid URL: " + uriString); _invalid++; Console.WriteLine("Count: " + (_invalid + _count)); Console.WriteLine("----------------------------------------------"); } } } private static void UpdateItem(IAsyncResult result) { try { // grab the custom state object RequestState state = (RequestState)result.AsyncState; WebRequest request = (WebRequest)state.Request; // get the Response HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); Stream s = (Stream)response.GetResponseStream(); StreamReader readStream = new StreamReader(s); // dataString will hold the entire contents of the requested page if we need it. string dataString = readStream.ReadToEnd(); response.Close(); s.Close(); readStream.Close(); //Console.WriteLine(dataString); Console.WriteLine("Site HTML: " + state.SiteUrl); } catch { RequestState state = (RequestState)result.AsyncState; WebRequest request = (WebRequest)state.Request; Console.WriteLine("Couldn't Resolve URL: " + state.SiteUrl); } Interlocked.Increment(ref _count); Console.WriteLine("Count: " + (_invalid + _count)); Console.WriteLine("----------------------------------------------"); // All URL look-ups complete if ((_count + _invalid) == _total) { Console.WriteLine("Complete!"); } } private static void ScanTimeoutCallback(object state, bool timedOut) { if (timedOut) { RequestState reqState = (RequestState)state; if (reqState != null) { reqState.Request.Abort(); } Console.WriteLine("aborted- timeout"); } } class RequestState { public WebRequest Request; // holds the request public object Data; // store any data in this public string SiteUrl; // holds the UrlString to match up results (Database lookup, etc). public RequestState(WebRequest request, object data, string siteUrl) { this.Request = request; this.Data = data; this.SiteUrl = siteUrl; } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload