Wednesday, October 13, 2010

Using Parallel.Invoke with dynamic number of Actions

 

The new Task Parallel Library (new in NET 4.0) is an excellent and (relatively) crazy-easy way of improving application performance.   In this article, we show how to use one of the methods in the library (Parallel.Invoke) to simultaneously execute a method with runtime-determined number of threads.

Let us take the case of an Order fullfilment piece that takes orders and submits them for processing.

Step 1: Retrieve the list of approved Orders.

    1         class Order

    2         {

    3             public int OrderID;

    4             public Order(int orderID)

    5             {

    6                 this.OrderID = orderID;

    7             }

    8         }

    9 

   10        static private List<Order> GetApprovedOrders()

   11         {

   12             List<Order> orders;

   13 

   14             orders = new List<Order>();

   15 

   16             for (int i = 0; i < 100; i++)

   17             {

   18                 orders.Add(new Order(i));

   19             }

   20 

   21             return orders;

   22         }

 

Step 2: Divide up the list depending on the number of concurrent tasks.

    1         static private List<List<Order>> DivideUpWork(List<Order> orders, int nThreads)

    2         {

    3             List<List<Order>> list;

    4 

    5             list = new List<List<Order>>();

    6 

    7             for (int i = 0; i < nThreads; i++)

    8             {

    9                 List<Order> sublist = orders.Where((c, j) => j % nThreads == i).ToList<Order>();

   10                 list.Add(sublist);

   11             }

   12 

   13             return list;

   14         }

Step 3: Define the “work” method that will take a list of orders and submit them for processing.   In this sample case, all the “work” is to just the display the OrderID.

    1         static private void ProcessOrders(int threadNumber, List<Order> orders)

    2         {

    3             for (int i = 0; i < orders.Count; i++)

    4             {

    5                 Console.WriteLine(String.Format("{0} of {1}: {2}", threadNumber, orders.Count - 1, orders[i].OrderID));

    6             }

    7         }

Step 4: Now, tie them all and call Parallel.Invoke().   The key here is to “parameterize” each invocation of ProcessOrder().    Since the System.Action delegate does not allow for any parameters, we workaround this in Line 16 using closure.   The assignment in Line 15 ensures that each call to ProcessOrder will be unique. 

    1         static void Main(string[] args)

    2         {

    3             int nThreads;

    4             Action[] actions;

    5             List<Order> orders;

    6             List<List<Order>> ordersByThread;

    7 

    8             nThreads       = 8;

    9             orders         = GetApprovedOrders();

   10             ordersByThread = DivideUpWork(orders, nThreads);

   11 

   12             actions = new Action[nThreads];

   13             for (int i = 0; i < nThreads; i++)

   14             {

   15                 int local_i = i;

   16                 actions[local_i] = () => { ProcessOrders(local_i, ordersByThread[local_i]); };

   17             }

   18 

   19             Parallel.Invoke(actions);

   20         }

Full program is here.

Technorati Tags: ,

Tuesday, August 31, 2010

How to set your Silverlight application to always test in Internet Explorer

 

Right-click on your start page and Select ‘Browse With’

image 

Select Internet Explore and click on Set Default

image

 

Technorati Tags:

Tuesday, July 6, 2010

Tracing inside SQL Server Stored Procedures

 

One of the best ways to understand the workings of an application is to trace the interaction between the application and the database.   For SQL Server-based applications, the SQL Server Profiler is the tool that allows you to peek behind the scenes.

By default, the Profiler only lists the the stored procedures that the application calls directly.  For example, if the application calls a Level1 stored procedure, you will see this in the Profiler results:

image

For the most part, I find to be sufficient to get a handle on what is going on.  But there will be those times where you would want to dig deeper and trace into the individual lines inside the stored procedure..

To do this:

  1. Go to the Properties window
  2. Go to the Event Selection tab.
  3. Check Show All Events
  4. Check the SP:StmtStarting event inside the Stored Procedure group.

image

After you Click on Run and let your application execute, you will see the individual line statements in the stored procedure and anything else it may call.

image

Saturday, June 26, 2010

Using Regular Expression Groups in Search and Replace

I needed to convert a series of numbers as in:

          19473
          20390
          22797
          23116
          ..

into

          list.Add(19473);
          list.Add(20390);
          list.Add(22797);
          list.Add(23116);
          ...

While I am not adverse to doing this manually or thru some macro, I was staring at 10000 of these so I can just hear my old boss saying "You are not lazy enough."

The solution is to use regular expressions. Using NotePad++,

 SearchAndReplace

The key here was to enclose in parenthesis the search pattern and reference that in the replace string as \1.

Sweet!

Tuesday, November 4, 2008

Broken Rules in the Domain

Technorati Tags:

I've been using the broken rules scheme in my past few projects and I like the way it raises the visibility of rules by making them a first class citizen of the domain. Rules will no longer be buried with the other "stuff" of a business transaction.  No sir, these rules have names! 

Take for example, a couple of rules around issuing inventory for a title insurance company:

  1. Provide the ability for management to block requests for new inventory from a specific agency.
  2. Provide the ability to stop issuing inventory to agencies whose contract has been canceled.
  3. Provide the ability to stop issuing inventory to agencies that have failed to meet minimum reporting requirements .
  4. Provide the ability to stop agencies from being issued inventory they are not authorized for.

Speaking close to the language of the domain, these rules are grouped as a set.  And for the sake of brevity, let us assume that these rules are independent of each other:

 

        private List<ValidationRuleBase> GetRulesForIssuingInventory(Agent agent, PolicyType requestedPolicyType, List<PolicyType> policyTypesAuthorizedForTheAgent)

        {

            var rules = new List<ValidationRuleBase>();

 

            rules.Add(new ShouldNot_Issue_To_Agents_That_Has_Been_Blocked_To_RequestInventory(agent));

            rules.Add(new ShouldNot_Issue_To_Cancelled_Agents(agent));

            rules.Add(new ShouldNot_Issue_To_Agents_That_Has_Not_Met_Minimum_Reporting_Requirements(agent));

            rules.Add(new Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes(agent,requestedPolicyType, policyTypesAuthorizedForTheAgent));

 

            return rules;

        }

 


In this particular scenario, this set of rules hangs off the domain object 'Order'  and is checked when a request for inventory is received.

 

        public void PlaceAnOrder(Order order)

        {

            List<ValidationRuleBase> rules;

            List<ValidationRuleBase> brokenRules;

 

            rules = order.GetRulesForIssuingInventory(order.Agent, order.PolicyType, order.Agent.AuthorizedPolicyTypes);

            brokenRules = GetBrokenRules(rules);

            if (brokenRules.Count>0)

            {

                throw new BusinessRuleException(brokenRules);

            }

 

            // continue with the rest of the placing an order transaction

        }

 

 

An example of a rule implementation is:

 

    public class Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes : ValidationRuleBase

    {

        private Agent agent;

        private PolicyType requestedPolicyType;

        private List<PolicyType> policyTypesAuthorizedForTheAgent;

 

        public Agent_ShouldBe_Authorized_To_Order_The_Requested_PolicyTypes(Agent agent, PolicyType requestedPolicyType, List<PolicyType> policyTypesAuthorizedForTheAgent)

        {

            this.agent                            = agent;

            this.requestedPolicyType              = requestedPolicyType;

            this.policyTypesAuthorizedForTheAgent = policyTypesAuthorizedForTheAgent;

        }

 

        override public bool IsValid

        {

            get

            {

                return this.policyTypesAuthorizedForTheAgent.Contains(this.requestedPolicyType);

            }

        }

 

        public override string Message

        {

            get

            {

                return String.Format("Policy Type {0} is not in the list of policy types Agent {1} can order.",this.requestedPolicyType.Name,this.agent.Name);

            }

        }

    }

 

 

Note in the IsValid() override that the heart of the rule is for the most part just plain logic and is devoid of UI and persistence concerns.   This leads to a more focused expression of the rule.