views:

169

answers:

2

I have this class called SiteAsyncDownload.cs

Here's the code:

public class SiteAsyncDownloader
{
    WebClient Client = new WebClient();
    string SiteSource = null;

    /// <summary>
    /// Download asynchronously the source code of any site in string format.
    /// </summary>
    /// <param name="URL">Site URL to download.</param>
    /// <returns>Website source code - string.</returns>
    public string GetSite(string URL)
    {
        Uri Site = new Uri(URL);

        Client.DownloadDataAsync(Site);
        Client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(FinishedDownloading);

        //Don't know if this would work. Consult with StackOverflow.
        while (true)
        {
            if (SiteSource != null)
            {
                return SiteSource;
            }
        }            
    }

    void FinishedDownloading(object sender, DownloadDataCompletedEventArgs e)
    {
        SiteSource = Encoding.ASCII.GetString(e.Result);
        throw new NotImplementedException();
    }
}

I'm not 100% if this would work as I want it to. I want the class to download whatever it needs to asynchronously and when done downloading return the string. Is this the right approach?

For instance, here's an example of how I intend to use it:

SiteAsyncDownloader Downloader = new SiteAsyncDownloader();

    /// <summary>
    /// Search for a movie using only a name.
    /// </summary>
    /// <param name="MovieName">Movie name.</param>        
    public void SearchMovie(string MovieName)
    {
        string SearchURL = FormatSearch(MovieName);

        string SearchSource = Downloader.GetSite(SearchURL);

        string MovieURL = FindMovieURL(SearchSource);
        string MovieSource = Downloader.GetSite(MovieURL);

        FindInformation(MovieSource);
    }

In the second line of code in the SearchMovie() method, will my program crash because it's of the async download? How can I take this into account and have it work properly?

+1  A: 

While it will probably work, it's a bad idea. There's no point in using asynchronous APIs if you're immediately going to block until the results have come through. If you really can't do any more work in that thread until you've got the data, and you've only got one request, just use a synchronous API. Further, the way you're blocking is to just tight loop, which will cause your processor to spin for no reason.

On a slightly different matter, I wouldn't use Encoding.ASCII if I were you - you should honour whatever encoding the server sends. Using DownloadStringAsync is the easiest way of doing that.

Jon Skeet
Jon, I'm only using asynchronous methods so my GUI doesn't freeze while my program downloads the sites source code. Will my code NOT freeze the source code?On another note, I'm kinda new to web scraping. Instead of using encoding.ASCII, what can I use to download a websites source code for my scraping purposes?
Sergio Tapia
Argh...typo. *Will my code NOT freeze my GUI?
Sergio Tapia
It will lockup the GUI, because your `while (true)` just goes around in a _very_ tight loop until the value is retrieved, which takes (all of the) CPU time away from the GUI.
nasufara
Thanks for comment Darkassasin. What do you recommend I do to fix this.
Sergio Tapia
Look at the links in my answer, they should put you on your way. You can also Google event and callback pattern, which can give you more resources as well.
nasufara
+2  A: 

What you're trying to do here:

while (true)

Will just spin up the CPU until the operation is done, defeating the point of it being asynchronous in the first place. You would need to use the event pattern or the callback pattern.

nasufara