using System;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            HttpWebRequest req = WebRequest.Create("http://www.google.com") as HttpWebRequest;
            MemoryStream memStream = new MemoryStream();
            HttpWebResponse resp = null;

            // anonymous delegate to handle cleanup
            EventHandler Cleanup = (s, ev) =>
                {
                    using (resp)
                    {
                    }
                    resp = null;
                    using (memStream)
                    {
                    }
                    memStream = null;
                };

            // anonymous method to handle errors
            EventHandler Error = (s, ev) =>
            {
                MessageBox.Show((s as Exception).Message);
                Cleanup(null, null);
            };

            req.BeginGetResponse(responseResult =>
                { // anonymous delegate that waits for a response from the web server
                    Thread.Sleep(1000); // for asynchronous testing
                    try
                    {
                        resp = req.EndGetResponse(responseResult) as HttpWebResponse;
                        Stream responseStream = resp.GetResponseStream();
                        byte[] buffer = new byte[1024];
                        AsyncCallback rc = null;
                        rc = readResult =>
                            { // anonymous delegate that waits to read a some data from the web server
                                Thread.Sleep(1000); // for asynchronous testing
                                try
                                {
                                    int read = responseStream.EndRead(readResult);
                                    if (read > 0)
                                    {
                                        memStream.Write(buffer, 0, read);
                                        responseStream.BeginRead(buffer, 0, buffer.Length, rc, null);
                                    }
                                    else
                                    {
                                        // We finished downloading! Invoke the UI thread to print the data!

                                        // anonymous delegate to handle completion
                                        EventHandler Done = (s, ev) =>
                                        {
                                            memStream.Seek(0, SeekOrigin.Begin);
                                            string blob = new StreamReader(memStream).ReadToEnd();
                                            Cleanup(null, null);
                                            MessageBox.Show(blob);
                                        };

                                        Invoke(Done);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Invoke(Error, ex);
                                }
                            };
                        responseStream.BeginRead(buffer, 0, buffer.Length, rc, null);
                    }
                    catch (Exception ex)
                    {
                        Invoke(Error, ex);
                    }
                },
                null);
        }
    }
}