Anonymous Delegate ThreadPool calls


By Peter Bromberg
Printer Friendly Version
  

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.


Biography
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking ,financial and telephony for 20 years. Pete focuses exclusively on the .NET Platform, and his samples at GotDotNet.com have been downloaded over 56,000 times. Peter enjoys producing 3D raytraced digital photo collage with Maya, the beach, and fine wines. You can view Peter's UnBlogIttyUrl, and BlogMetafinder sites.
Please post questions at forums, not via email!

button
 
Article Discussion: Shows how to use Anonymous Delegates on ThreadPool calls
  Peter Bromberg posted at 04-Jan-08 12:59
Original Article