Listing 1

namespace Original_Async_Delegate
{
  class NetworkBlock
  {
    public string GetPage(string Url, int Port, bool Secure)
    {
      // ... fetch the page
      return "<html>...</html>";
    }
  }
  class TestAsyncDelegate
  {
    public delegate string 
      AsyncGetPage(string Url, int Port, bool Secure);
    static void ResultCallback(IAsyncResult ar)
    {
      AsyncGetPage agp = (AsyncGetPage)ar.AsyncState;
      String result = agp.EndInvoke(ar);
    }
    [STAThread]
    static void Main(string[] args)
    {
      NetworkBlock net = new NetworkBlock();
      AsyncGetPage agp = new AsyncGetPage(net.GetPage);
      // 1. synchronously wait
      IAsyncResult ar1 = agp.BeginInvoke("http...", 80, false, null, null);
      string res1 = agp.EndInvoke(ar1);
      // 2. wait on async result
      IAsyncResult ar2 = agp.BeginInvoke("ftp...", 21, false, null, null);
      ar2.AsyncWaitHandle.WaitOne();
      string result2 = agp.EndInvoke(ar2);
      // 3. loop waiting for completed flag
      IAsyncResult ar3 = agp.BeginInvoke("https...", 81, true, null, null);
      while(!ar3.IsCompleted)
        Thread.Sleep(10);
      string result3 = agp.EndInvoke(ar3);
      // 4. use async callback for result
      IAsyncResult ar4 = agp.BeginInvoke("ftp...", 21, false, 
        new AsyncCallback(ResultCallback), agp);
    }
  }
}