Anonymous Delegate ThreadPool calls

Anonymous methods are not an intrinsic construct of the CLR. They are actually implemented by the C# compiler. This short article illustrates how to use anonymous delegates with the .NET ThreadPool.

 Anonymous methods offer a language construct to create an inline declared delegate pattern. The compiler generates the implementation code so that it is created automatically instead of the developer having to write it.

Here is a sample Console Application that pumps out 10 Threadpool QueueUserWorkItem calls, with the delegate to handle the callbacks written inline via an anonymous method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading; 

namespace DelegateInvokeOnThreadPool
{
    class Program
    {
        static void Main(string[] args)
        {
            for(int i =0;i<10;i++)
            {
                DoWork();
            }
            Console.ReadLine();
        } 

        private static int ctr = 0;
        private static void DoWork()
        {
            // Do work on ThreadPool thread. We can have our delegate inline
            ThreadPool.QueueUserWorkItem(
                delegate
                {
                    Exception ex = null;
                     WebClient wc=null;
                    string result = null;
                    try
                    {
                      wc = new WebClient();
                        result = wc.DownloadString("http://petesbloggerama.blogspot.com/rss.xml");
                        result = result.Substring(0, 200); // chop it off to manageable size
                        //put some space before and after so easier to see in Console Window...
                        ctr++;
                        result += "\r\n\r\n\r\n>>>> THIS WAS NUMBER " + ctr.ToString() + " <<<<\r\n\r\n\r\n";
                    }
                    catch (Exception ex2)
                    {
                        ex = ex2;
                    }
                    finally
                    {
                        if(wc!=null)
                        wc.Dispose();
                        // Handle results 
                        if (ex != null)
                            Console.WriteLine(ex.Message);
                        else
                            Console.WriteLine(result);
                        result = String.Empty;
                    }
                });
        }
      }
}
Here (in C#) is what the compiler is actually doing in the above code:

[CompilerGenerated]
private static WaitCallback CS$<>9__CachedAnonymousMethodDelegate1;
private static void DoWork() {
if (CS$<>9__CachedAnonymousMethodDelegate1 == null)
{ CS$<>9__CachedAnonymousMethodDelegate1 = delegate { //... rest of code from above here... } ThreadPool.QueueUserWorkItem(CS$<>9__CachedAnonymousMethodDelegate1);
Outer Variables

When you declare a variable outside an anonymous method and access it within the implementation  it is called an outer variable. Outer variable are are available only when you use an anonymous method where you "capture" the variable such that the compiler takes care of passing it, along with your delegate, and returning it at the end of the invocation. Note that in the above example the "ctr" variable is declared outside the anonymous method but is actually incremented inside it.
By Peter Bromberg   Popularity  (3325 Views)