Execution Context

It is quite interesting to see how many people don’t understand the basics of threading, while it is a difficult topic (especially to debug), and it is not the silver bullet for all the problems, but it sure is quite handy for certain things. With the inevitable shift to multi-core CPU’s and the release of Vista to take better opportunity of these extra power, more applications in the future should be ready to exploit them. Which makes it quite important for the average developer to start playing and understanding this.

If you are new to this, one of the classes I would recommend reading up on is called ExecutionContext class. This class essentially is the equivalent of the COM Apartment (from the good old COM days). This class provides a single container for all information relevant to a logical thread of execution which includes security context, call context, synchronization context, localization context, and transaction context. You cannot change context of the thread (to which a ExecutionContext is attached), you can only copy it to another thread. If you do try and copy it you will get an Exception.

Here is an example from MSDN on how to use this (also testing the new CopyAsHTML Addin):

    1 using System;

    2 using System.Threading;

    3 using System.Security;

    4 using System.Collections;

    5 using System.Security.Permissions;

    6 using System.Runtime.Serialization;

    7 using System.Runtime.Remoting.Messaging;

    8 

    9 namespace Contoso

   10 {

   11     class ExecutionContextSample

   12     {

   13         static void Main()

   14         {

   15             try

   16             {

   17                 Console.WriteLine(“Executing Main in the primary thread.”);

   18                 FileDialogPermission fdp = new FileDialogPermission(

   19                     FileDialogPermissionAccess.OpenSave);

   20                 fdp.Deny();

   21                 // Capture the execution context containing the Deny.

   22                 ExecutionContext eC = ExecutionContext.Capture();

   23 

   24                 // Suppress the flow of the execution context.

   25                 AsyncFlowControl aFC = ExecutionContext.SuppressFlow();

   26                 Thread t1 = new Thread(new ThreadStart(DemandPermission));

   27                 t1.Start();

   28                 t1.Join();

   29                 Console.WriteLine(“Is the flow suppressed? “ +

   30                     ExecutionContext.IsFlowSuppressed());

   31                 Console.WriteLine(“Restore the flow.”);

   32                 aFC.Undo();

   33                 Console.WriteLine(“Is the flow suppressed? “ +

   34                     ExecutionContext.IsFlowSuppressed());

   35                 Thread t2 = new Thread(new ThreadStart(DemandPermission));

   36                 t2.Start();

   37                 t2.Join();

   38                 // Remove the Deny.

   39                 CodeAccessPermission.RevertDeny();

   40                 // Capture the context that does not contain the Deny.

   41                 ExecutionContext eC2 = ExecutionContext.Capture();

   42                 // Show that the Deny is no longer present.

   43                 Thread t3 = new Thread(new ThreadStart(DemandPermission));

   44                 t3.Start();

   45                 t3.Join();

   46 

   47                 // Set the context that contains the Deny.

   48                 // Show the deny is again active.

   49                 Thread t4 = new Thread(new ThreadStart(DemandPermission));

   50                 t4.Start();

   51                 t4.Join();

   52                 // Demonstrate the execution context methods.

   53                 ExecutionContextMethods();

   54                 Console.WriteLine(“Demo is complete, press Enter to exit.”);

   55                 Console.Read();

   56             }

   57             catch (Exception e)

   58             {

   59                 Console.WriteLine(e.Message);

   60             }

   61         }

   62         // Execute the Demand.

   63         static void DemandPermission()

   64         {

   65             try

   66             {

   67                 Console.WriteLine(“In the thread executing a Demand for “ +

   68                     “FileDialogPermission.”);

   69                 new FileDialogPermission(

   70                     FileDialogPermissionAccess.OpenSave).Demand();

   71                 Console.WriteLine(“Successfully demanded “ +

   72                     “FileDialogPermission.”);

   73             }

   74             catch (Exception e)

   75             {

   76                 Console.WriteLine(e.Message);

   77             }

   78         }

   79 

   80         static void ExecutionContextMethods()

   81         {

   82             // Generate a call context for this thread.

   83             ContextBoundType cBT = new ContextBoundType();

   84             cBT.GetServerTime();

   85             ExecutionContext eC1 = ExecutionContext.Capture();

   86             ExecutionContext eC2 = eC1.CreateCopy();

   87             Console.WriteLine(“The hash code for the first execution “ +

   88                 “context is: “ + eC1.GetHashCode());

   89 

   90             // Create a SerializationInfo object to be used for getting the

   91             // object data.

   92             SerializationInfo sI = new SerializationInfo(

   93                 typeof(ExecutionContext),

   94                 new FormatterConverter());

   95 

   96             eC1.GetObjectData(

   97                 sI,

   98                 new StreamingContext(StreamingContextStates.All));

   99 

  100             LogicalCallContext lCC = (LogicalCallContext)sI.GetValue(

  101                 “LogicalCallContext”,

  102                 typeof(LogicalCallContext));

  103 

  104             // The logical call context object should contain the previously

  105             // created call context.

  106             Console.WriteLine(“Is the logical call context information “ +

  107                 “available? “ + lCC.HasInfo);

  108         }

  109     }

  110 

  111 

  112     // One means of communicating between client and server is to use the

  113     // CallContext class. Calling CallContext effectivel puts the data in a thread

  114     // local store. This means that the information is available to that thread

  115     // or that logical thread (across application domains) only.

  116     [Serializable]

  117     public class CallContextString : ILogicalThreadAffinative

  118     {

  119         String _str = “”;

  120 

  121         public CallContextString(String str)

  122         {

  123             _str = str;

  124             Console.WriteLine(“A CallContextString has been created.”);

  125         }

  126 

  127         public override String ToString()

  128         {

  129             return _str;

  130         }

  131     }

  132 

  133     public class ContextBoundType : ContextBoundObject

  134     {

  135         private DateTime starttime;

  136 

  137         public ContextBoundType()

  138         {

  139             Console.WriteLine(“An instance of ContextBoundType has been “ +

  140                 “created.”);

  141             starttime = DateTime.Now;

  142         }

  143         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)]

  144         public DateTime GetServerTime()

  145         {

  146             Console.WriteLine(“The time requested by a client.”);

  147             // This call overwrites the client’s

  148             // CallContextString.

  149             CallContext.SetData(

  150                 “ServerThreadData”,

  151                 new CallContextString(“This is the server side replacement “ +

  152                 “string.”));

  153             return DateTime.Now;

  154         }

  155     }

  156 

  157 }

Published by

Amit Bahree

This blog is my personal blog and while it does reflect my experiences in my professional life, this is just my thoughts. Most of the entries are technical though sometimes they can vary from the wacky to even political – however that is quite rare. Quite often, I have been asked what’s up with the “gibberish” and the funny title of the blog? Some people even going the extra step to say that, this is a virus that infected their system (ahem) well. [:D] It actually is quite simple, and if you have still not figured out then check out this link – whats in a name?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.