23

My plan is to have a user write down a movie title in my program and my program will pull the appropiate information asynchronously so the UI doesn't freeze up.

Here's the code:

public class IMDB
    {
        WebClient WebClientX = new WebClient();
        byte[] Buffer = null;


        public string[] SearchForMovie(string SearchParameter)
        {
            //Format the search parameter so it forms a valid IMDB *SEARCH* url.
            //From within the search website we're going to pull the actual movie
            //link.
            string sitesearchURL = FindURL(SearchParameter);

            //Have a method download asynchronously the ENTIRE source code of the
            //IMDB *search* website.
            Buffer = WebClientX.DownloadDataAsync(sitesearchURL);


            //Pass the IMDB source code to method findInformation().

            //string [] lol = findInformation();

            //????

            //Profit.

            string[] lol = null;
            return lol;
        }

My actual problem lies in the WebClientX.DownloadDataAsync() method. I can't use a string URL for it. How can I use that built in function to download the bytes of the site (for later use I will convert this to string, I know how to do this) and without freezing up my GUI?

Perhaps a clear cut example of the DownloadDataAsync so I can learn how to use it?

Thanks SO, you're always such a great resource.

4
  • 3
    Re IMDB: terms page: "Robots and Screen Scraping: You may not use data mining, robots, screen scraping, or similar data gathering and extraction tools on this site, except with our express written consent as noted below.". I strongly suggest that you do not this; it is clearly against their rules. Commented Oct 18, 2009 at 20:53
  • 1
    Marc, what other site has information like IMDB that I CAN use? Thanks for the help. Commented Oct 18, 2009 at 21:22
  • @Sergio developer.rottentomatoes.com Commented Apr 4, 2013 at 8:48
  • @SergioTapia also, themoviedb.org and thetvdb.com which I believe both have APIs you can use to access the data directly and save yourself alot of time. ;) Commented Feb 24, 2016 at 16:38

6 Answers 6

41

There is a newer DownloadDataTaskAsync method that allows you to await the result. It is simpler to read and easier to wire up by far. I'd use that...

var client = new WebClient();

var data = await client.DownloadDataTaskAsync(new Uri(imageUrl));

await outstream.WriteAsync(data, 0, data.Length);
Sign up to request clarification or add additional context in comments.

3 Comments

But do this is not the same to do the call in a sync way? (It is DownloadDataTask and in this case you will receive the result directly), if you want to do an async call I think this is not an option, because is working like sync.
It uses async/await with the Task class. It is asynchronous as much as the above answer is. The only difference is you use a continuation method DownloadDataCompleted in the above and you use an await to inline the continuation in my version. If you wanted progress reporting or the like I might do it differently but if you just want a continuation on completion this way works just as well with less code.
If you want to do other things while the Task is running you just don't await it and do your stuff, then add a continuation to it. Check this out for info.
33

You need to handle the DownloadDataCompleted event:

static void Main()
{
    string url = "http://google.com";
    WebClient client = new WebClient();
    client.DownloadDataCompleted += DownloadDataCompleted;
    client.DownloadDataAsync(new Uri(url));
    Console.ReadLine();
}

static void DownloadDataCompleted(object sender,
    DownloadDataCompletedEventArgs e)
{
    byte[] raw = e.Result;
    Console.WriteLine(raw.Length + " bytes received");
}

The args contains other bits of information relating to error conditions etc - check those too.

Also note that you'll be coming into DownloadDataCompleted on a different thread; if you are in a UI (winform, wpf, etc) you'll need to get to the UI thread before updating the UI. From winforms, use this.Invoke. For WPF, look at the Dispatcher.

2 Comments

Just to dot-the-i, there is a standard pattern for handling DownloadDataCompleted, like for RunWorkerCompleted, see msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx
as Bill Forney said, DownloadDataTaskAsync is a better solution
5
static void Main(string[] args)
{
    byte[] data = null;
    WebClient client = new WebClient();
    client.DownloadDataCompleted += 
       delegate(object sender, DownloadDataCompletedEventArgs e)
       {
            data = e.Result;
       };
    Console.WriteLine("starting...");
    client.DownloadDataAsync(new Uri("http://stackoverflow.com/questions/"));
    while (client.IsBusy)
    {
         Console.WriteLine("\twaiting...");
         Thread.Sleep(100);
    }
    Console.WriteLine("done. {0} bytes received;", data.Length);
}

Comments

4

If anyone using above in web application or websites please set Async = "true" in the page directive declaration in aspx file.

Comments

1
ThreadPool.QueueUserWorkItem(state => WebClientX.DownloadDataAsync(sitesearchURL));

http://workblog.pilin.name/2009/02/system.html

Comments

0

//using ManualResetEvent class

static ManualResetEvent evnts = new ManualResetEvent(false);
static void Main(string[] args)
{
    byte[] data = null;
    WebClient client = new WebClient();
    client.DownloadDataCompleted += 
        delegate(object sender, DownloadDataCompletedEventArgs e)
        {
             data = e.Result;
             evnts.Set();
        };
    Console.WriteLine("starting...");
    evnts.Reset();
    client.DownloadDataAsync(new Uri("http://stackoverflow.com/questions/"));
    evnts.WaitOne(); // wait to download complete

    Console.WriteLine("done. {0} bytes received;", data.Length);
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.