Covariance and Contravariance in C# 4.0

C# 4.0 introduces the notion of Covariance and Contravariance of generic type parameters for interfaces and delegate types. Eric Lippert has put together a bunch of posts that goes into details of the why and how, an excellent read but not for the faint of heart. I would strongly suggest reading these posts to get a firm grounding and a better appreciation of this feature. It took me a while to get my head wrapped around this, especially since none of the VS2010 Betas were not out at the time and there was no way to try out any code. Now that I have Beta2 of VS2010 at hand I decided to try out some code samples first hand and solidify my understanding of the feature.

Suppose we have the following inheritance hierarchy:

 
  1. interface IAnimal  
  2. {  
  3.     void Speak();  
  4. }  
  5.   
  6. class Whale : IAnimal  
  7. {  
  8.      public void  Speak()  
  9.     {  
  10.          Console.WriteLine("I'm a Whale");  
  11.     }  
  12. }  
  13.   
  14. class Giraffe : IAnimal  
  15. {  
  16.     public  void Speak()  
  17.     {  
  18.         Console.WriteLine("I'm a Giraffe");  
  19.     }  
  20. }  

 

and a processor to process animals:

 
  1. interface IProcessor<T>  
  2. {  
  3.     void Process(IEnumerable<T> ts);     
  4. }  
  5.   
  6. class Processor<T> : IProcessor<T> where T:IAnimal  
  7. {  
  8.     public void Process(IEnumerable<T> ts)  
  9.     {  
  10.         foreach (var t in ts)  
  11.         {  
  12.             t.Speak();  
  13.         }  
  14.     }          
  15. }  

 

It would be natural to be able to create a Processor to process any kind of animal, but the following code does not compile today on the C# 3.0 compiler

 
  1. List<Giraffe> giraffeList = new List<Giraffe> { new Giraffe() };  
  2. IProcessor<IAnimal> proc = new Processor<IAnimal>();  
  3. proc.Process(giraffeList);  
We have to add a silly"OfType<IAnimal>" cast to make it work:
 
  1. List<Giraffe> giraffeList = new List<Giraffe> { new Giraffe() };  
  2. IProcessor<IAnimal> proc = new Processor<IAnimal>();  
  3. proc.Process(giraffeList.OfType<IAnimal>());  

 

In C# 4.0 no such cast is needed and everything just works as expected. Why? because in .NET 4.0 IEnumerable<T> is covariant in it's type parameter T, this is what the definition looks like

 
  1. public interface IEnumerable<out T> : IEnumerable  
  2. {  
  3. ....  
  4. ....  
  5. }   
The "out" keyword is what makes the "T" covariant; which means that you can pass in any type which is more derived than "T" as the type argument, hence we can pass in IEnumerable<Giraffe> or IEnumerable<Whale> to the Process method which accepts an IEnumerable<IAnimal> and everything just works as expected in a type safe way.

 

You can define your own covariant types to allow for such conversions.
Consider the following generic class definition to create instances of a specified type
 
  1. interface IFactory<out T>  
  2. {  
  3.     T CreateInstance();  
  4. }  
  5.   
  6. class Factory<T> : IFactory<T> where T: new()  
  7. {  
  8.     public T CreateInstance()  
  9.     {  
  10.         return new T();  
  11.     }          
  12. }  
IFactory<T> is covariant in T so we can treat a Factory<Giraffe> as an IFactory<IAnimal>. This allows us to treat factories of types in the same inheritance chain uniformly like so:
 
  1. IFactory<IAnimal> giraffeFactory = new Factory<Giraffe>();  
  2. IFactory<IAnimal> whaleFactory = new Factory<Whale>();  
  3.   
  4. List<IFactory<IAnimal>> factories = new List<IFactory<IAnimal>>{ giraffeFactory, whaleFactory };  
  5. foreach (var factory in factories)  
  6. {  
  7.     factory.CreateInstance().Speak();  
  8. }  

Note that it is illegal for a covariant type parameter to occur in an input position, it can only occur in output positions such as return type of a method in the type. This restriction is key in making covariance work,allowing the type parameter in an input position would break covariance. How you might ask. Imagine if the following illegal code were legal and you could specify T in an input position.

 
  1. interface IFactory<out T>    
  2. {  
  3.     T CreateInstance();  
  4.     T CreateInstanceFrom(T t);  
  5. }  
  6.   
  7. class Factory<T> : IFactory<T>  
  8.     where T : new()  
  9.     where T : ICloneable  
  10. {  
  11.     public T CreateInstance()  
  12.     {  
  13.         return new T();  
  14.     }  
  15.     public T CreateInstanceFrom(T t)  
  16.     {  
  17.         return (T)t.Clone();  
  18.     }  
  19.   
  20. }  
We added a constraint to the factory class to constrain the type parameter to support ICloneable and added a new method CreateInstanceFrom which accept the instance to clone. Now what happens if we do the following:
 
  1. IFactory<IAnimal> giraffeFactory = new Factory<Giraffe>();  
  2. giraffeFactory.CreateInstanceFrom(new Whale())  
Oh my! we just passed in a Whale to clone a Giraffe, and we'd bomb a runtime.
It is precisely for this reason that a covariant type parameter can only occur in output positions(hence the keyword out) and the runtime error is now a compile time error.

 

But what if we wanted to have the type paramter in an input position to get the benefits variance has to offer, enter contrvariance which is the dual of covariance. In that a type argument can be safely replaced by a more derived type but only in an input position.

If T appears ONLY in an input position (such as a parameter in methods of IProcessor) then we can mark T as contravariant using the in keyword, allowing us to substitute any sub type of T.

 
  1. interface IProcessor<in T>  
  2. {  
  3.     void Process(IEnumerable<T> ts);  
  4. }  

This makes assignments such as the following legal.

 
  1. List<Giraffe> giraffes = new List<Giraffe> { new Giraffe() };  
  2. List<Whale> whales = new List<Whale> { new Whale() };  
  3. IProcessor<IAnimal> animalProc = new Processor<IAnimal>();  
  4. IProcessor<Giraffe> giraffeProcessor = animalProc;  
  5. IProcessor<Whale> whaleProcessor = animalProc;  
  6. giraffeProcessor.Process(giraffes);  
  7. whaleProcessor.Process(whales);  

 

Finally let's look at variance in delegate types. Consider the following delegate definition and it's subsequent usage

 
  1. public delegate void MyAction<in T>(T t);  
  2. ........  
  3. .......  
  4. .........  
  5.  MyAction<IAnimal> animalAction = a => a.Speak();  
Since T is contravariant, we can treat MyAction<IAnimal> as MyAction<Giraffe> since Giraffe is more derived than IAnimal
  1. MyAction<Giraffe> rafAction = animalAction;  

 

Now let's combine both co and contravariance, consider the following delegate

 
  1. public delegate T2 MyFunc<in T1,out T2>(T1 t1);  
T2 is covariant and T1 is contravariant and hence we can use T1 or any subtypes of T1 as the first generic type paramter and T2 or any of its base types as the second generic type parameter, allowing us to use assignments such as the following with full type safety
 
  1. Func<IAnimal, Giraffe> func = a => a as Giraffe;  
  2. Func<Giraffe, IAnimal> funcG = func;  

 

Covariance and Contravariance may sound like a mouthful and daunting to understand but at its core it's quite simple to grasp once you understand its purpose, it enables writing generic code more naturally and allows safe type coercions. That's it for today. Happy coding.

T4 template consuming a WCF service

It’s been a while since I’ve blogged and but I have a valid excuse; I moved to WA state recently and things have been crazy busy. I finally decided to kick myself and do a post so without further ado, the problem at hand:
A co-worker of mine asked me whether its possible to dynamically create a type from some data he is receiving from a WCF service (over HTTP).
My natural response was, why would you need to do that since Visual Studio creates a proxy from the metadata exposed by the service and the return types would typically be DataContracts.
Well, it turns out that instead of returning a strongly typed domain specific object, the service is returning a Dictionary<string,string> where the Key represents an attribute and the Value represents the value of the attribute.

This has obvious problems:

  • Nothing is strongly typed
  • No contract versioning
  • The service could return a variable number of fields
A naive approach is to inspect the data returned by the service and hand code a class with properties based on the type of each key in the Dictionary.
For example, if the Dictionary contained the following KeyValuePairs.
{“Name”,”Jon Smith”}
{“Age”,”20”}
{“Zip”,”90876”}

The class definition would look something like this:
 
  1. public class User  
  2. {  
  3.   public string Name {get;set;}  
  4.   public int Age {get;set;}  
  5.   public int Zip {get;set;}  
  6. }  

That’s fine when you have a couple of KeyValuePairs but what if you had 10 or 20, it gets unwieldy very quickly.
Enter T4 templates, a slick way to generate code for repetitive tasks. I'd never written a T4 template before so I figured this would be a nice excuse to dabble in it a little.

Let’s create a simple service to simulate some data, nothing too fancy

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.Text;  
  7.   
  8. namespace T4WCFService  
  9. {  
  10.     [ServiceContract]  
  11.     public interface IT4WCFService  
  12.     {  
  13.   
  14.         [OperationContract]  
  15.         Dictionary<string,string> GetUser(string userID);         
  16.     }  
  17. }  
and its implementation...
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.Text;  
  7.   
  8. namespace T4WCFService  
  9. {  
  10.     public class T4Service : IT4WCFService  
  11.     {  
  12.  
  13.         #region IT4WCFService Members  
  14.   
  15.         public Dictionary<stringstring> GetUser(string userID)  
  16.         {  
  17.             if (userID == "jsmith")  
  18.             {  
  19.                 return new Dictionary<stringstring>   
  20.                         {   
  21.                             { "Name""Jack smith" },  
  22.                             { "Age""30" },   
  23.                             { "City""San francisco" },  
  24.                             { "State""CA"  },   
  25.                             { "Zip""94061"  },  
  26.                             { "Country""USA"  }   
  27.   
  28.   
  29.                         };    
  30.             }  
  31.             if (userID == "jasmith")  
  32.             {  
  33.                 return new Dictionary<stringstring>   
  34.                         {   
  35.                             { "Name""Jane smith" },  
  36.                             { "Age""28" },   
  37.                             { "City""Portland" },  
  38.                             { "State""OR"  },   
  39.                             { "Zip""98685"  },  
  40.                             { "Country""USA"  }   
  41.                         };  
  42.             }  
  43.             return new Dictionary<stringstring>();              
  44.         }  
  45.  
  46.         #endregion  
  47.     }  
  48. }  

The service just simulates returning some dummy users based on a userID and returns an empty Dictionary if no matching user is found, and it’s exposed using
WSHttpBinding

The <system.servicemodel> looks as follows:
 
  1. <system.serviceModel>  
  2.   <services>  
  3.     <service behaviorConfiguration="T4WCFService.Service1Behavior"  
  4.       name="T4WCFService.T4Service">  
  5.       <endpoint address="WsHttpT4Service" binding="wsHttpBinding" name="WsHttpT4Service"  
  6.         contract="T4WCFService.IT4WCFService">  
  7.         <identity>  
  8.           <dns value="localhost" />  
  9.         </identity>  
  10.       </endpoint>  
  11.       <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />  
  12.       <endpoint address="basicHttpTService" binding="basicHttpBinding"  
  13.         name="basicHttpTService" contract="T4WCFService.IT4WCFService" />  
  14.       <host>  
  15.         <baseAddresses>  
  16.           <add baseAddress="http://WCFServices" />  
  17.         </baseAddresses>  
  18.       </host>  
  19.     </service>  
  20.   </services>  
  21.   <behaviors>  
  22.     <serviceBehaviors>  
  23.       <behavior name="T4WCFService.Service1Behavior">  
  24.         <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->  
  25.         <serviceMetadata httpGetEnabled="true"/>  
  26.         <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->  
  27.         <serviceDebug includeExceptionDetailInFaults="false"/>  
  28.       </behavior>  
  29.     </serviceBehaviors>  
  30.   </behaviors>  
  31. </system.serviceModel>  

If you(like me) have never created a T4 template before, I’d strongly suggest reading this article first.

Welcome back, now that you know how to create a simple T4 template, let’s get started.
T4 enables writing reusable modules that can be consumed from other T4 modules. For the purpose of this exercise I decided to create a template which encapsulates invoking a WCF service and returning the result back to the caller.

Create a new Console Application and add a service reference to the service we created above, also add a new T4 file to your project called WCFServiceInvoker.tt

T4_WCFServiceInvoker

Double click on WCFServiceInvoker.tt and the file should open up in markup mode.Delete the default code in the .tt file and add the following code:

 
  1. <#@ template language="C#v3.5"#>  
  2. <#@ output extension=".cs"#>   
  3. <#@ assembly name ="System.ServiceModel" #>   
  4. <#@ import namespace="System.Collections.Generic"#>  
  5. <#@ import namespace="System.Reflection"#>  
  6. <#@ import namespace="System.ServiceModel.Channels"#>  
  7. <#@ import namespace="System.ServiceModel"#>  
  8.   
  9. <#+  
  10.     public class WCFServiceInvoker<TInterfaceType,TReturnType> where TReturnType:class  
  11.     {  
  12.       public string EndPointAddress {get;set;}  
  13.       public string EndPointName {get;set;}  
  14.       public Type ServiceInterfaceType {get;set;}        
  15.       public Binding Binding {get;set;}  
  16.       public string MethodName {get;set;}  
  17.       public object[] Parameters {get;set;}  
  18.       public TReturnType InvokeMethod()  
  19.       {  
  20.             EndpointAddress endpoint = new EndpointAddress(EndPointAddress);  
  21.             Type typeDef = typeof(ChannelFactory<>).MakeGenericType(typeof(TInterfaceType));  
  22.             var typeInst = Activator.CreateInstance(typeDef,new object[]{Binding,endpoint});  
  23.             var channel = typeInst.GetType().InvokeMember("CreateChannel", BindingFlags.InvokeMethod,null, typeInst, null);  
  24.             var results = channel.GetType().InvokeMember(MethodName, BindingFlags.InvokeMethod, null,channel, Parameters);  
  25.             return results as TReturnType;  
  26.       }  
  27.         
  28.     }  
  29. #>  

There is a lot going on here.

  • The template and output directives indicate that the code is written in C# and the generated file needs to be have an extension of .cs.
  • The <#@assembly> directive is similar to an “Add Reference” in Visual Studio, it allows for referencing external assemblies.
  • The <#@import> directive is similar to a “using” statement, in that it brings the types in the specified namespace in scope so that the template can avail of them.
  • The <#+ #> directive is called Class feature block and it allows for writing class definitions within the template.
    This allows for encapsulating reusable logic.
    NOTE: The class definitions in this block are not emitted out to the final .cs file.
  • The WCFServiceInvoker class contains a bunch of properties, whose values(when set) are used for invoking a specified service dynamically.
  • The type parameters “TInterfaceType” represents the type of the interface on which the method specified in the "MethodName" parameter will be invoked.
  • The type parameter “TReturnType” represents the type of the result returned from the method call.

Using “TInterfaceType” we dynamically create a type definition for ChannelFactory<T> using reflection, and then create an instance of it, on which we then call CreateChannel which in turns returns us an instance of a type which implements TInterfaceType. Once we have a “TInterfaceType” instance we then go ahead and invoke the specified “MethodName” with the parameters specified in the “Parameters” object[] property and get the result back which is typed to “TReturnType” and returned to the caller.

Phew! that’s a mouthful and we are not done yet. For now just keep in mind that this template is merely a helper which encapsulates the details on dynamically invoking a WCF service in a strongly typed manner.

Now onto the main task of writing a template to solve our problem.

Add another T4 template to the project and call it UserClass.tt
T4_UserClass

As before delete the code from the .tt file and add the following:

 
  1. <#@ assembly name ="System.ServiceModel" #>   
  2. <#@ assembly name ="T4WCFService.dll" #>   
  3. <#@ assembly name ="System.ServiceModel" #>   
  4. <#@ import namespace="System.Collections.Generic"#>  
  5. <#@ import namespace="System.Reflection"#>  
  6. <#@ import namespace="System.ServiceModel.Channels"#>  
  7. <#@ import namespace="System.ServiceModel"#>  
  8. <#@ import namespace="T4WCFService"#>  
  9. <#@ include file="WCFServiceInvoker.tt" #>  
  10. using System.Collections.Generic;  
  11. namespace T4ClassFromDict  
  12. {  
  13.     public class User  
  14.     {  
  15.         <#  
  16.         WCFServiceInvoker<IT4WCFService,Dictionary<string,string>> invoker = new WCFServiceInvoker<IT4WCFService,Dictionary<string,string>>();  
  17.         invoker.EndPointAddress = "http://localhost:24551/Service1.svc/WsHttpT4Service";  
  18.         invoker.EndPointName = "WsHttpT4Service";  
  19.         invoker.ServiceInterfaceType = typeof(IT4WCFService);  
  20.         invoker.Binding = new WSHttpBinding();  
  21.         invoker.MethodName = "GetUser";  
  22.         invoker.Parameters = new object[]{"jsmith"};      
  23.         Dictionary<string,string> result = invoker.InvokeMethod();  
  24.         #>  
  25.          <#foreach(KeyValuePair<string,string> item in result){  
  26.          #>  
  27.            
  28.          public <#= item.Key.GetType().Name.ToLower()#> <#=item.Key#>  
  29.          {  
  30.              get;         
  31.              set;  
  32.          }  
  33.          <#}#>  
  34.            
  35.          public static User GetUser(Dictionary<string,string> dict)  
  36.          {  
  37.              var user = new User();  
  38.              foreach(KeyValuePair<string,string> kvp in dict)  
  39.              {  
  40.                 typeof(User).GetProperty(kvp.Key).SetValue(user,kvp.Value,null);                  
  41.              }  
  42.              return user;  
  43.          }  
  44.     }  
  45. }  

We've included the template file we created before so that we can reuse it to invoke any WCF Service.
We then proceed to create an instance of WCFServiceInvoker and set it's properties to invoke the WCF service we've created.
The result of "invoker.InvokeMethod()" is a Dictionary<string,string> which we then loop through creating public properties.

We use the type of the Key as the type of the property and the Key itself as the property name.

We've also created the definition of factory method which accepts a Dictionary<string,string> and returns a User object.

Note that we've added a direct reference to the service assembly in this template so that we can get a reference to IT4WCFService.
This is just to keep the example simple, ideally you would want to seperate the interface and implementation assemblies and have a reference to just the interface assembly.

T4 templates are executed typically when saved or by right clicking on the .tt file and selecting "Run Custom Tool".
Before running the template, ensure that the WCF service is up and running.

On running/saving the template, the following class definition is generated.

 
  1. using System.Collections.Generic;  
  2. namespace T4ClassFromDict  
  3. {  
  4.     public class User  
  5.     {  
  6.                            
  7.          public string Name  
  8.          {  
  9.              get;         
  10.              set;  
  11.          }  
  12.                    
  13.          public string Age  
  14.          {  
  15.              get;         
  16.              set;  
  17.          }  
  18.                    
  19.          public string City  
  20.          {  
  21.              get;         
  22.              set;  
  23.          }  
  24.                    
  25.          public string State  
  26.          {  
  27.              get;         
  28.              set;  
  29.          }  
  30.                    
  31.          public string Zip  
  32.          {  
  33.              get;         
  34.              set;  
  35.          }  
  36.                    
  37.          public string Country  
  38.          {  
  39.              get;         
  40.              set;  
  41.          }  
  42.                    
  43.          public static User GetUser(Dictionary<string,string> dict)  
  44.          {  
  45.              var user = new User();  
  46.              foreach(KeyValuePair<string,string> kvp in dict)  
  47.              {  
  48.                 typeof(User).GetProperty(kvp.Key).SetValue(user,kvp.Value,null);                  
  49.              }  
  50.              return user;  
  51.          }  
  52.     }  
  53. }  

A client can then use the generates class as follows:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Net;  
  6. using System.IO;  
  7. using System.ServiceModel;  
  8. using T4WCFService;  
  9. using System.Reflection;  
  10.   
  11.   
  12. namespace T4ClassFromDict  
  13. {    
  14.   
  15.     class Program  
  16.     {  
  17.   
  18.         public string Foo { getset; }  
  19.         static void Main(string[] args)  
  20.         {            
  21.             var client = new T4Service.T4WCFServiceClient("WsHttpT4Service");  
  22.             var data = User.GetUser(client.GetUser("jsmith"));  
  23.         }  
  24.     }  
  25. }  

NOTE: The console app hosting the project has a direct project reference to WCF service project since it needs the IT4WCFService definition. and since T4 engine is running inside Visual studio it locks the assembly, so rebuilding the WCF service after template generation does not work.
As mentioned previously the solution to this is to have seperate assemblies for the interface and service implementation.
Download Code

Why no Anonymous Iterators in C#

Yes I’m a language geek and yes the awesome  Eric Lippert is my idol when it comes to anything C# and the CLR, I’ve been following his blog for a long time and recently Eric wrote an awesome series on the how and why of Iterator Blocks. The entire series is very well worth a read, but then again I’d read almost anything Eric writes from why the sky is blue to why the Falkirk Wheel has horns.

I had posed a question on this post about why there are no anonymous iterators in C#. Eric provided a very good answer to that comment and I was highly flattered when he did a follow up post on this very question here.

Thanks Eric!

Creating Higher Level APIs with TPL

The BCL has a bunch of APIs which provide asynchronous versions of operations in the form of either Beginxxx/Endxxx or XyzCompleted, the former known as Asynchronous Programming Model(APM) and the latter known as Event Based Asynchronous Pattern (EAP). TPL provides a nice abstraction for performing asynchronous operations as Tasks using delegates, but what can you do for working with these existing BCL classes which already have an async version?

Here is an example.
Let's say we need to download some data from the web and save it to a file, you would typically use the WebClient class and write something like this today (wrapped in a method of course)
  1. WebClient client = new WebClient();  
  2.            client.DownloadDataAsync(new Uri("http://www.bing.com"));  
  3.            client.DownloadDataCompleted += new DownloadDataCompletedEventHandler((s, e) =>  
  4.            {  
  5.                if (e.Error != null)  
  6.                {  
  7.                    throw e.Error;  
  8.                }  
  9.                if (!e.Cancelled)  
  10.                {  
  11.                    using (FileStream fs = new FileStream("bing.htm", FileMode.CreateNew))  
  12.                    {  
  13.                        fs.Write(e.Result,0,e.Result.Length);  
  14.                        fs.Flush();  
  15.                        fs.Close();  
  16.                    }  
  17.                }  
  18.            }  
  19.            );  
  20.            Console.Read();  

Yuck not very pretty is it! It's kinda smelly and looking at the code, it doesn't really capture the essense of what we are trying to do, besides if the client were to call a method which does this work, we'd have to ensure that the client thread blocks till the continuation completes or conversely provide a mechanism such as a WaitHandle that the client can wait on, not very expressive is it?


Let's see how we can achieve the same results using the Task API.
 
  1. private static TaskCompletionSource<byte[]> CreateSource(object state)  
  2. {  
  3.     return new TaskCompletionSource<byte[]>(state);  
  4. }  
  5.   
  6. private static void SetCompletionSource<T>(  
  7.     TaskCompletionSource<T> tcs,  
  8.     AsyncCompletedEventArgs e,  
  9.     Func<T> getResult)  
  10. {  
  11.     if (e.UserState == tcs)  
  12.     {  
  13.         if (e.Cancelled)  
  14.             tcs.TrySetCanceled();  
  15.         else  
  16.             if (e.Error != null) tcs.TrySetException(e.Error);  
  17.         else  
  18.             tcs.TrySetResult(getResult());  
  19.     }  
  20. }  
  21.   
  22. public static Task<byte[]> DownloadBytesTask(this WebClient webClient, string uri)  
  23. {  
  24.     var source = CreateSource(uri);  
  25.     DownloadDataCompletedEventHandler handler = null;  
  26.     handler = (object s, DownloadDataCompletedEventArgs e) =>  
  27.     {  
  28.         SetCompletionSource(source, e, () => e.Result);  
  29.         webClient.DownloadDataCompleted -= handler;  
  30.     };  
  31.     webClient.DownloadDataAsync(new Uri(uri), source);  
  32.     webClient.DownloadDataCompleted += handler;  
  33.     return source.Task;  
  34. }  

We've wrapped up the async network operation into a Task as an extension method.
Let's dig in a little...

In DownloadBytesTask, we first create a TaskCompletionSource which provides a mechanism to create a Task to hand out to consumers such that the only legal state modification to the Task can be performed via the methods available on the TaskCompletionSource itself and not on the instance of the Task directly, this is precisely the behavior needed for a Task that is downloading content from the web asynchronously;it doesn't make sense for the client to explicitly start such a Task which has already started downloading data and such an operation should really be considered illegal, TaskCompletionSource enables this behavior.

In the callback we call SetCompletionSource which is responsible for transitioning the state of the Task based on the results of the asynchronous operation such as whether it errored out, or completed or whether it was cancelled.

We then proceed to start the asynchronous download by calling DownloadDataAsync method of the WebClient instance.

Couple of things to note:

  • The callback has been unhooked from the event in the callback to ensure that we don't have a memory leak.
  • The Task has already started since "DownloadDataAsync" has already been invoked, and it is this started Task that we return from the method.
The client can now perform the asynchronous download and saving of content like so:
 
  1. public class Program  
  2. {  
  3.         public static Task WriteToFileTask(string fileName, byte[] bytes)  
  4.         {  
  5.             FileStream fs = new FileStream(fileName, FileMode.CreateNew);  
  6.             var task = Task.Factory.FromAsync(fs.BeginWrite, fs.EndWrite, bytes, 0, bytes.Length, null);  
  7.             return task;  
  8.         }  
  9.   
  10.         static void Main(string[] args)  
  11.         {  
  12.             WebClient wc = new WebClient();  
  13.             var task = wc.DownloadBytesTask("http://www.bing.com/");                                     
  14.             var continuationTask = task.ContinueWith(a => WriteToFileTask("bing.htm", a.Result));  
  15.             continuationTask.Wait();              
  16.         }  
  17. }  

The DownloadBytes extension method on the WebClient returns a Task which has already started, we then specify a continuation to execute "after" the Task completes by calling the "ContinueWith" method on the Task instance which in this case is itself a Task which works on the result of the antecedent task (a byte[]) obtained by calling the "WriteToFileTask" method which is responsible for writing out the byte[] to a file.

It's important to note that we have to wait for the "continuation" to complete by calling continuationTask.Wait(), otherwise the process will terminate since we are running on a console app. The same would hold true in case of a Webforms client since the calling Page would continue processing and not wait for the Task to complete.

Notice how the client code seems pretty terse in terms of expressing the intent. One can easily read the code and figure out what's going on.
As always happy coding!

CLR via C# 3rd Edition

Some book news…Jeff Richter is one of my favorite authors and I’ll read just about anything he writes. His last book CLR via C#, 2nd Edition left me wanting more, luckily Jeff has signed into a contract for writing a 3rd edition of the book updated for C#3.0/4.0 and .NET 4.0

Retrieving Added Entities from the ObjectStateManager to avoid duplication

Let's say we neede to process a bunch of entities coming from an XML file, create EDM entites for each XML element and eventually persist them. Very trivial to accomplish using a little bit of LINQ.

  1. <Roles>  
  2.   <Role name="Admin"/>  
  3.   <Role name="Reader"/>  
  4.   <Role name="Writer"/>    
  5. </Roles>  

  1. var doc = XDocument.Load("Roles.xml");  
  2. var roles = doc.Element("Roles").Elements("Role").Select(x => new Role { RoleName = (string)x.Attribute("name") });  
  3. PermissionsAPIContext context = new PermissionsAPIContext();  
  4.   
  5. foreach (var role in roles)  
  6. {  
  7.   context.AddToRoleSet(role);  
  8. }  
  9. context.Savechanges()  
But wait, let's make this a little interesting...

  1. <Roles>  
  2.   <Role name="Admin"/>  
  3.   <Role name="Reader"/>  
  4.   <Role name="Writer"/>  
  5.   <Role name="Reader"/>  
  6. </Roles>  
See the problem now? If we process the above XML using the code from before, we end up adding the same entity twice!
So what do we do now?
ObjectStateManager to the rescue, let's rewrite the piece of code as follows:

  1. var doc = XDocument.Load("Roles.xml");  
  2. var roles = doc.Element("Roles").Elements("Role").Select(x => (string)x.Attribute("name"));  
  3. PermissionsAPIContext context = new PermissionsAPIContext();  
  4. foreach (var role in roles)  
  5. {  
  6.    Role roleEntity = GetRole(role, context);  
  7.    if (roleEntity.EntityState == EntityState.Added || roleEntity.EntityState == EntityState.Detached)  
  8.    {  
  9.       context.AddToRoleSet(roleEntity);  
  10.    }                  
  11.  }  
  12. context.SaveChanges();  
  13.   
  14.   
  15. private static Role GetRole(string roleName,PermissionsAPIContext context)  
  16. {  
  17.   //NOTE: we could have used string.Compare(r.RoleName,roleName,true) == 0 inside the body of the lambda as a cleaner   
  18.   //way to do this but this translates to some pretty snarly and inefficient SQL!  
  19.     var roleEntity = context.RoleSet.FirstOrDefault(r => r.RoleName.Trim().ToLower() == roleName.Trim().ToLower());  
  20.     if (roleEntity == null)  
  21.      {  
  22.            var stateEntries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EtityState.Modified | EntityState.Unchanged);  
  23.            var roleEntityEntries = stateEntries.Select(s => s.Entity).OfType<Role>();  
  24.            roleEntity = roleEntityEntries.FirstOrDefault(r => r.RoleName.Trim().ToLower() == roleName.Trim().ToLower());  
  25.            if (roleEntity == null)  
  26.            {  
  27.                return new Role { RoleName = roleName };  
  28.            }  
  29.      }  
  30.      return roleEntity;  
  31. }  
A few of things note worthy here
1) In GetRoles() we first query the ObjectContext to check whether there is already a role present with the given name, if so we 
    simply return a reference to the existing entity instance
2) If the role is not existing then we check to see whether a role with the given name was added to the context, if so then we just
    get a handle to this previously added(but not yet persisted) role and return that.
3) If the role is not existing and was not added previously then we create a new Role entity and return.
4) The caller checks whether the returned entity is an existing one and if not it's added to the ObjectContext.

After we are done processing all entities, we save all entities and we are done.

The above mechanism allows us to safely sidestep duplicates while processing based on some equality rule(which in this case happens to be the role name).

Hope this helps.

Inside TPL video

No code today. Instead, here is a link to a great video from Channel9 I found, which takes a deep dive into the underlying mechanics of how TPL does what it does and some of the enhancements that the thread pool has undergone.  Albeit a year old, this video goes into details of the work stealing algorithm and local thread queues that helps increase throughput.

From the perspective of being a consumer of TPL, you can be blissfully ignorant of what happens behind the scenes, but understanding the mechanics and some of the design decisions that the team made can help gain a deeper appreciation of TPL which ultimately can help write more thoughtful code.

I was impressed by the clarity in which the concepts were presented and explained.  Plan on setting aside about an hour to watch this video, but every minute is time well spent!

Performing multiple Asynchronous Actions using TPL

I finally had a chance to install VS2010 Beta 1.Full instruction on how to here
VS2010 has undergone a major overhaul since VS 2008, a peek are some of the cool new eye candy can be found here
I've been waiting to get my hands on the TPL/PLINQ stuff and the Beta was definitely worth the wait. In a previous post we talked about using asynchronous actions for performing long running operations.

I was anxious to see how the new TPL stuff would help in achieving the same thing.

Interestingly enough, the TPL API is based on Actions as well, allowing both the generic and non-generic versions to be used for creating a Task(also supports Funcs).

The Thread pool has undergone some major rework, especially the scheduling algorithm is much more smarter now than the current implementation in.NET 3.5

The unit of abstraction is a Task as opposed to a Thread, so let's dive in and see how this looks and feels as opposed to the abstraction we previously built for asynchronous Actions. In the simplest form, the equivalent declaration for creating a Task that can execute an Action asynchronously looks like so:

 

 
  1.  public static void SomeMethod()  
  2.  {  
  3.   
  4.      // do something here....  
  5.      Console.WriteLine("In some method");  
  6.   
  7.  }   
  8.   
  9. static void Main(string[] args)  
  10. {  
  11.     var task = Task.Factory.StartNew(SomeMethod);  
  12.    task.Wait();  
  13.  }  

You start a task and Wait for it to complete. Lets create a bunch of these tasks to execute on the GetUsers(), GetCountries() and GetLanguages() method from the previous post.

 

 
  1. Task[] tasks = new Task[]  
  2. {  
  3.    Task.Factory.StartNew(() => countries = GetCountries()),  
  4.    Task.Factory.StartNew(() => countries = GetUsers()),  
  5.    Task.Factory.StartNew(() => countries = GetLanguages())  
  6. };  
  7. Task.WaitAll(tasks);  

This looks fairly similar from a usage persepctive to what we had for executing asynchronous actions

 
  1. List<Action> actions = new List<Action>()  
  2. {  
  3.     () => countries = GetCountries(),  
  4.     () => users = GetUsers(),  
  5.     () => languages = GetLanguages(),  
  6. };          
  7. actions.ExecAsync();  

One obviously noticeable difference in using the Task is that you use the Factory method StartNew to create and execute the task at the point of declaration, and what you get back is a handle to the executing Task. So the Task[] contains a handle to all the executing tasks.
The ExecAsync extension method on the other hand is passed a collection of Actions to execute. I find the idea of being able to create and execute the Task in one statement very useful and terse.

Let's now compare the performance of executing Actions using Tasks v/s executing Actions using The ExecAsync()

 

 
  1. public static class Extensions  
  2.    {  
  3.        public static void ExecAsync(this IEnumerable<Action> actions)  
  4.        {  
  5.            int count = 0;  
  6.            AutoResetEvent[] events = new AutoResetEvent[actions.Count()];  
  7.            IAsyncResult[] results = new IAsyncResult[actions.Count()];  
  8.            for (int i = 0; i < events.Length; i++)  
  9.            {  
  10.                events[i] = new AutoResetEvent(false);  
  11.            }  
  12.   
  13.            foreach (var action in actions)  
  14.            {  
  15.                int localCount = count;  
  16.                results[count++] =  
  17.                    action.BeginInvoke((r) =>  
  18.                    {  
  19.                        try  
  20.                        {  
  21.                            if (r.IsCompleted)  
  22.                            {  
  23.                                Action act = r.AsyncState as Action;  
  24.                                act.EndInvoke(results[localCount]);  
  25.                            }  
  26.                        }  
  27.                        finally  
  28.                        {  
  29.                            //set the event regardless of whether there is an exception so that the main thread  
  30.                            //is not blocked indefinitely.  
  31.                            events[localCount].Set();  
  32.                        }  
  33.                    }, action);  
  34.            }  
  35.            WaitHandle.WaitAll(events);  
  36.        }  
  37.    }  
  38.   
  39.    public class Program  
  40.    {  
  41.        public static string[] GetUsers()  
  42.        {  
  43.            //simulate a long running operation  
  44.            Thread.SpinWait(3000);  
  45.            Console.WriteLine("Current Thread:{0}", Thread.CurrentThread.ManagedThreadId);  
  46.            return new[] { "Jack""Jon""Jim" };  
  47.        }  
  48.   
  49.        public static string[] GetCountries()  
  50.        {  
  51.            //simulate a long running operation  
  52.            Thread.SpinWait(3000);  
  53.            Console.WriteLine("Current Thread:{0}", Thread.CurrentThread.ManagedThreadId);  
  54.            return new[] { "US""UK""Canada" };  
  55.        }  
  56.   
  57.        public static string[] GetLanguages()  
  58.        {  
  59.            //simulate a long running operation  
  60.            Thread.SpinWait(3000);  
  61.            Console.WriteLine("Current Thread:{0}", Thread.CurrentThread.ManagedThreadId);  
  62.            return new[] { "English""French""German" };  
  63.        }  
  64.        static void Main(string[] args)  
  65.        {  
  66.   
  67.            string[] countries;  
  68.            string[] users;  
  69.            string[] languages;  
  70.            List<Action> actions = new List<Action>()  
  71.            {  
  72.                () => countries = GetCountries(),  
  73.                () => users = GetUsers(),  
  74.                () => languages = GetLanguages(),  
  75.            };  
  76.            Console.WriteLine("Running Actions Asynchronously");  
  77.            Console.WriteLine("----------------------");  
  78.            Stopwatch watch = Stopwatch.StartNew();  
  79.            actions.ExecAsync();  
  80.            watch.Stop();  
  81.            Console.WriteLine("Total time taken:{0} milliseconds", watch.ElapsedMilliseconds);  
  82.   
  83.            Console.WriteLine();  
  84.            Console.WriteLine("Running Actions using Tasks");  
  85.            Console.WriteLine("----------------------");  
  86.            watch.Reset();  
  87.            watch.Start();  
  88.            Task[] tasks = new Task[]  
  89.            {  
  90.               Task.Factory.StartNew(() => countries = GetCountries()),  
  91.               Task.Factory.StartNew(() => countries = GetUsers()),  
  92.               Task.Factory.StartNew(() => countries = GetLanguages())  
  93.            };  
  94.            Task.WaitAll(tasks);  
  95.            watch.Stop();  
  96.            Console.WriteLine("Total time taken:{0} milliseconds", watch.ElapsedMilliseconds);  
  97.        }  
  98.    }  

Let's give it a spin and see the numbers:

The version using Tasks is almost 5 times faster! which suggests that TPL is doing a far superior job under the covers in effectively scheduling and executing the Actions.
TPL has a host of goodness which I've barely started exploring.Among other goodies, is the ability to have parent-child relationships between tasks and support for cancellation using a CancellationToken.
I hope to do more frequent posts especially around TPL since this has piqued my interest.
As always happy coding!

kick it on DotNetKicks.com

Using multiple Object Contexts in a Transaction

The scenario: You have 2 Entity Models, and you need to call operations on the ObjectContext of each of them, the operations should be atomic, in that either both operations should succeed or fail so that your databases are consistent.
This is fairly straightforward to accomplish using a TransactionScope.
ObjectServices is smart enough to detect if the ObjectContext is in a surrounding TransactionScope and if so,use that scope.
NOTE:If a scope is not specified, then ObjectContext by default creates a new scope internally when saving changes.

 
  1. using (TransactionScope scope = new TransactionScope())  
  2.            {  
  3.                using (RequestDBContext context = new RequestDBContext())  
  4.                {  
  5.                    RequestType rt = new RequestType  
  6.                    {  
  7.                         Name="Test-2",                            
  8.                    };  
  9.                    context.AddToRequestTypeSet(rt);  
  10.                    context.SaveChanges();  
  11.                }  
  12.   
  13.                using (RequestDBContext context = new RequestDBContext())  
  14.                {  
  15.                      
  16.                    Status stat = context.StatusSet.First(s => s.Name == "Pending Approval");  
  17.                    context.DeleteObject(stat);  
  18.                    context.SaveChanges();  
  19.                }  
  20.                scope.Complete();  
  21.            }  

In the above code I'm using the same EDM for both ObjectContexts, but I could very well use different EDMs.
If we reach the end of the 2nd using statement, then we can complete the transaction and persist all our changes.
If an exception is thrown then nothing is changed in the database and the transaction aborts.
Hope this helps.


UPDATE:5/16/09
Using TransactionScope requires MSDTC, the following links have good information to help setup/troubleshoot MSDTC for various environments
How to Enable MSDTC on a Web Server
New functionality in the Distributed Transaction Coordinator service in Windows Server 2003 Service Pack 1 and in Windows XP Service Pack 2
Thursday, February 19, 2009 5:08 PM mmazur How to configure and troubleshoot MSDTC

kick it on DotNetKicks.com

Handling WorkflowRuntime events for IIS hosted WCF + WF services

The WorkflowRuntime class has a host of interesting methods and useful events. Events such as Completed, Perssited, Idled are invaluable when debugging and in understanding how a workflow instance is behaving.
These events are easily accessible when self hosting the runtime since you can just hook up event handlers for these events and react to these events as you see fit.
But, when the workflow runtime is hosted in IIS/WAS/Cassini host, you don’t have a direct handle to the runtime for hooking up these events.
The .svc file for the WCF service contains the WorkflowServiceHostFactory that WCF uses for servicing workflow service requests.

 
  1. <%@ ServiceHost Language="C#"   
  2. Debug="true"   
  3. Service="RequestWFServiceLib.ApprovalWorkflow"  
  4. Factory="System.ServiceModel.Activation.WorkflowServiceHostFactory"%>  

We can easily subclass WorkflowServiceHostFactory and replace the Factory attribute in the .svc file with a custom implementation of this class where in we override the CreateServiceHost Method and get a handle to the WorkflowRuntime and hook up the event handlers we need.

 
  1.    public class CustomWorkflowServiceHost : WorkflowServiceHostFactory  
  2. {  
  3.   
  4.        public override System.ServiceModel.ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)  
  5.        {  
  6.            ServiceHostBase hostBase = base.CreateServiceHost(constructorString, baseAddresses);  
  7.            WorkflowRuntimeBehavior runtimeBehavior = hostBase.Description.Behaviors.Find<WorkflowRuntimeBehavior>();  
  8.            WorkflowRuntime runtime = runtimeBehavior.WorkflowRuntime;  
  9.            runtime.WorkflowIdled += runtime_WorkflowIdled;  
  10.            runtime.Started += runtime_Started;  
  11.            runtime.Stopped += runtime_Stopped;  
  12.            runtime.WorkflowStarted += runtime_WorkflowStarted;  
  13.            runtime.WorkflowSuspended += runtime_WorkflowSuspended;  
  14.            runtime.WorkflowUnloaded += runtime_WorkflowUnloaded;  
  15.            runtime.WorkflowCreated += runtime_WorkflowCreated;  
  16.            runtime.WorkflowTerminated += runtime_WorkflowTerminated;  
  17.            runtime.WorkflowResumed += runtime_WorkflowResumed;  
  18.            runtime.WorkflowPersisted += runtime_WorkflowPersisted;  
  19.            runtime.WorkflowLoaded += runtime_WorkflowLoaded;  
  20.            runtime.WorkflowCompleted += runtime_WorkflowCompleted;  
  21.            runtime.WorkflowAborted += runtime_WorkflowAborted;  
  22.            return hostBase;  
  23.   
  24.        }  
  25.   
  26.        void runtime_WorkflowAborted(object sender, WorkflowEventArgs e)  
  27.        {  
  28.            Debug.WriteLine(string.Format("WorkflowInstance {0} Aborted", e.WorkflowInstance.InstanceId.ToString()));  
  29.        }  
  30.   
  31.        void runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)  
  32.        {  
  33.            Debug.WriteLine(string.Format("WorkflowInstance {0} Completed", e.WorkflowInstance.InstanceId.ToString()));  
  34.        }  
  35.   
  36.        void runtime_WorkflowLoaded(object sender, WorkflowEventArgs e)  
  37.        {  
  38.            Debug.WriteLine(string.Format("WorkflowInstance {0} Loaded", e.WorkflowInstance.InstanceId.ToString()));  
  39.        }  
  40.   
  41.        void runtime_WorkflowPersisted(object sender, WorkflowEventArgs e)  
  42.        {  
  43.            Debug.WriteLine(string.Format("WorkflowInstance {0} Persisted", e.WorkflowInstance.InstanceId.ToString()));  
  44.        }  
  45.   
  46.        void runtime_WorkflowResumed(object sender, WorkflowEventArgs e)  
  47.        {  
  48.            Debug.WriteLine(string.Format("WorkflowInstance {0} Resumed", e.WorkflowInstance.InstanceId.ToString()));  
  49.        }  
  50.   
  51.        void runtime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)  
  52.        {  
  53.            Debug.WriteLine(string.Format("WorkflowInstance {0} Terminated", e.WorkflowInstance.InstanceId.ToString()));  
  54.        }  
  55.   
  56.        void runtime_WorkflowCreated(object sender, WorkflowEventArgs e)  
  57.        {  
  58.            Debug.WriteLine(string.Format("WorkflowInstance {0} Created", e.WorkflowInstance.InstanceId.ToString()));  
  59.        }  
  60.   
  61.        void runtime_WorkflowUnloaded(object sender, WorkflowEventArgs e)  
  62.        {  
  63.            Debug.WriteLine(string.Format("WorkflowInstance {0} Unloaded", e.WorkflowInstance.InstanceId.ToString()));  
  64.        }  
  65.   
  66.        void runtime_WorkflowSuspended(object sender, WorkflowSuspendedEventArgs e)  
  67.        {  
  68.            Debug.WriteLine(string.Format("WorkflowInstance {0} Suspended", e.WorkflowInstance.InstanceId.ToString()));  
  69.        }  
  70.   
  71.        void runtime_WorkflowStarted(object sender, WorkflowEventArgs e)  
  72.        {  
  73.            Debug.WriteLine(string.Format("WorkflowInstance {0} Started", e.WorkflowInstance.InstanceId.ToString()));  
  74.        }  
  75.   
  76.        void runtime_Stopped(object sender, WorkflowRuntimeEventArgs e)  
  77.        {  
  78.            Debug.WriteLine("Workflow runtime Stopped");  
  79.        }  
  80.   
  81.        void runtime_Started(object sender, WorkflowRuntimeEventArgs e)  
  82.        {  
  83.            Debug.WriteLine("Workflow runtime Started");  
  84.        }  
  85.   
  86.        void runtime_WorkflowIdled(object sender, WorkflowEventArgs e)  
  87.        {  
  88.            Debug.WriteLine("Workflow runtime Idled");  
  89.        }  
  90. }  

the .svc file is updated to include the name of our custom implementation. That’s all there is to it.

 
  1. <%@ ServiceHost Language="C#"   
  2. Debug="true"   
  3. Service="RequestWFServiceLib.ApprovalWorkflow"  
  4. Factory="RequestWFServiceLib.CustomWorkflowServiceHost"%>  

kick it on DotNetKicks.com