January 2008 - Posts

.NET SecureStrings

After the last ONETUG meeting a member came up to me and told me that SecureStrings did not work in .NET. As always I take this as a challenge, and sure enough the proof is in the code.

    1         //Sample borrowed from http://blogs.msdn.com/shawnfa/archive/2004/05/27/143254.aspx

    2         static void Main(string[] args)

    3         {

    4             Console.WriteLine("Please enter your password");

    5             SecureString password = GetPassword();

    6 

    7             Console.WriteLine("Your password was");

    8             PrintPassword(password);

    9 

   10             Console.WriteLine("Press any key to quit");

   11             Console.ReadKey();

   12         }

   13 

   14         /// <summary>

   15         /// Read a password from the console into a SecureString

   16         /// </summary>

   17         /// <returns>Password stored in a secure string</returns>

   18         public static SecureString GetPassword()

   19         {

   20             SecureString password = new SecureString();

   21 

   22             // get the first character of the password

   23             ConsoleKeyInfo nextKey = Console.ReadKey(true);

   24 

   25             while (nextKey.Key != ConsoleKey.Enter)

   26             {

   27                 if (nextKey.Key == ConsoleKey.Backspace)

   28                 {

   29                     if (password.Length > 0)

   30                     {

   31                         password.RemoveAt(password.Length - 1);

   32 

   33                         // erase the last * as well

   34                         Console.Write(nextKey.KeyChar);

   35                         Console.Write(" ");

   36                         Console.Write(nextKey.KeyChar);

   37                     }

   38                 }

   39                 else

   40                 {

   41                     password.AppendChar(nextKey.KeyChar);

   42                     Console.Write("*");

   43                 }

   44 

   45                 nextKey = Console.ReadKey(true);

   46             }

   47 

   48             Console.WriteLine();

   49 

   50             // lock the password down

   51             password.MakeReadOnly();

   52             return password;

   53         }

   54 

   55         /// <summary>

   56         /// Write the Secure string to the console

   57         /// </summary>

   58         /// <param name="password"></param>

   59         public static void PrintPassword(SecureString password)

   60         {

   61             IntPtr bstr = Marshal.SecureStringToBSTR(password);

   62 

   63             try

   64             {

   65                 Console.WriteLine(Marshal.PtrToStringBSTR(bstr));

   66             }

   67             finally

   68             {

   69                 Marshal.ZeroFreeBSTR(bstr);

   70             }

   71 

   72         }

Posted by sweisfeld | with no comments
Filed under:

Reflect on dll from the disk

Got a question after my reflection talk I gave to the User Group last week. The attendee wanted to load a dll from the disk and reflect on it. The assembly class has a LoadFile method that makes this easy as pie. Here is a code sample.

            //Read the dll from the disk
            Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "Microsoft.Practices.ObjectBuilder.dll");

            //Print out some information about it
            foreach (Module module in assembly.GetModules())
            {
                Console.WriteLine("{0}", module.Name);

                foreach (Type type in module.GetTypes())
                {
                    Console.WriteLine(" {0}", type.FullName);
                    foreach (MethodInfo method in type.GetMethods())
                    {
                        Console.WriteLine("  {0}", method.Name);
                    }
                }
            }

            Console.ReadKey();
Posted by sweisfeld | with no comments
Filed under:

Orlando VS2008 Installfest

Back in November we did the Orlando VS2008 Installfest, and I have got to commend Microsoft for this forward looking opportunity. With the release of any new product there are always barriers to migration. The largest revolve around incompatibilities with older applications, or in the case of Visual Studio the tedious task of upgrading all of ones source code to the newest toolset. While the conversions wizards that have been shipping with VS.NET for a while help with this task depending on the size of your project this is an arduous task.

While code migration and potential incompatibilities drives much of what enterprise users of VS.NET do, the smaller ISV, independent developers or those new to Visual Studio have a much different barrier adoption, the cost of the product. With the price for standard over $250 and professional over $800 this could prevent adoption of the product by those outside enterprises with large IT budgets. While Microsoft has, IMHO, made a great decision by positioning the Express suite with no cost, there is nothing like having the professional version of the tool. After all one would think that they don’t make the majority of there money by selling developer tools, but by selling copies of Windows Vista, Windows Server, and SQL Server for the stuff the developers write to run on.

So let me get off my soapbox and talk a little about the Installfest that the DevFish did for ONETUG here in Orlando. Long story short it was great! Microsoft gave away over 100 copies of the software, VS 2008 T-Shirts, and laptop stickers. There were laptops, power cords, and people everywhere, and most surprising off all is the dedication of the select few that were brave enough to bring there desktops. I think my favorite picture is the gentlemen that brought a suitcase to carry everything. In addition to Joe, I have got to give a big thanks to Brian for volunteering to managing the Install fest table. Good Work!


Posted by sweisfeld | with no comments
Filed under: ,

Pivot/Cross Tab Queries in SQL Server

There are many ways to turn rows of data into columns in SQL Server, I figured I would outline some of them and talk about some of the pro/cons of each.

Sample 1: Using the SQL Server 2005 PIVOT operator. This is a great feature of SQL Server 2005 but has 2 obvious limitations. First it requires you to know the items you are going to pivot over (you can get around this limitation by using dynamic SQL). Second it requires you to have SQL Server 2005.
--Sample 1
SELECT CustomerID, [1996] AS year1996, [1997] AS year1997, [1998] AS year1998
FROM
(
 SELECT CustomerID, OrderID, DATEPART(year, OrderDate) AS years
 FROM Orders) N
PIVOT
(
COUNT (OrderID)
FOR years IN
(
 [1996], [1997], [1998] )
) AS pvt
ORDER BY CustomerID


Sample 2: We can work around both of the limitations of the first sample by using our old friend the CASE statement. But since we have declared a variable we are limited to stored procedures. This is due to the fact that you cannot embed a sub-query in an aggregate function.
--Sample 2
DECLARE @year0 int

SET @year0 = (SELECT MIN(DATEPART(year, OrderDate)) FROM [Northwind].[dbo].[Orders])

SELECT
       CustomerID, 
       SUM(CASE WHEN DATEPART(year, OrderDate) = (@year0) THEN 1 ELSE 0 END) AS year_0,
       SUM(CASE WHEN DATEPART(year, OrderDate) = (@year0 + 1) THEN 1 ELSE 0 END) AS year_1,
       SUM(CASE WHEN DATEPART(year, OrderDate) = (@year0 + 2) THEN 1 ELSE 0 END) AS year_2
FROM Orders
GROUP BY CustomerID


Sample 3: However we can trick SQL Server into allowing us to embed the sub query if we hide it in a view.
--Sample 3
CREATE VIEW Step1
AS
SELECT
       CustomerID, 
       (CASE WHEN DATEPART(year, OrderDate) = (SELECT MIN(DATEPART(year, OrderDate)) FROM Orders) THEN 1 ELSE 0 END) AS year_0,
       (CASE WHEN DATEPART(year, OrderDate) = (SELECT MIN(DATEPART(year, OrderDate)) + 1 FROM Orders) THEN 1 ELSE 0 END) AS year_1,
       (CASE WHEN DATEPART(year, OrderDate) = (SELECT MIN(DATEPART(year, OrderDate)) + 2 FROM Orders) THEN 1 ELSE 0 END) AS year_2
FROM Orders

CREATE VIEW Step2
AS
SELECT
       CustomerID,
       SUM(year_0) AS year_0,
       SUM(year_1) AS year_1,
       SUM(year_2) AS year_2
FROM Step1
GROUP BY CustomerID

SELECT *
FROM Step2


So with these variations you have a few extra tools in your tool box for converting rows into columns.

Posted by sweisfeld | with no comments
Filed under:

Is this really me?

This was given to me by one of my co-workers. . .

Posted by sweisfeld | with no comments
Filed under:

Using the CCR for web service calls

So I figured I would see how the CCR compared the traditional .NET 2.0 Web Service model so I threw together this demo application. The interesting thing is that while I wired up the async call back events first, most of the CCR results arrived first.

Web Service

    1         [WebMethod]

    2         public string Echo(string message, int sleep)

    3         {

    4             System.Threading.Thread.Sleep(sleep);

    5             return message;

    6         }

Test Harness

    1         static void Main(string[] args)

    2         {

    3             int sleeptime = 100;

    4 

    5             //Call using traditional sequential model

    6             Console.WriteLine("traditional sequential test");

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

    8             {

    9                 using (CCRService.Service1 ws = new CCRServiceTest.CCRService.Service1())

   10                 {

   11                     ws.Credentials = System.Net.CredentialCache.DefaultCredentials;

   12                     Console.WriteLine(ws.Echo(string.Format("Seq Message {0}", i), sleeptime));

   13                 }

   14             }

   15 

   16             //Call using traditional Async Model

   17             Console.WriteLine("traditional Async Model test");

   18             for (int i = 0; i < 5; i++)

   19             {

   20                 using (CCRService.Service1 ws = new CCRServiceTest.CCRService.Service1())

   21                 {

   22                     ws.Credentials = System.Net.CredentialCache.DefaultCredentials;

   23                     ws.EchoCompleted += new CCRServiceTest.CCRService.EchoCompletedEventHandler(

   24                         delegate(object sender, CCRServiceTest.CCRService.EchoCompletedEventArgs e)

   25                         {

   26                             Console.WriteLine(e.Result);

   27                         });

   28 

   29                     ws.EchoAsync(string.Format("Async Message {0}", i), sleeptime);

   30                 }

   31             }

   32 

   33             //Call using the CCR

   34             Console.WriteLine("CCR test");

   35             DispatcherQueue dq = new DispatcherQueue();

   36             Port<int> work = new Port<int>();

   37 

   38             for (int i = 0; i < 5; i++)

   39             {

   40                 work.Post(i);

   41             }

   42 

   43             Arbiter.Activate(dq,

   44                 Arbiter.Receive(true, work,

   45                 delegate(int i)

   46                 {

   47                     using (CCRService.Service1 ws = new CCRServiceTest.CCRService.Service1())

   48                     {

   49                         ws.Credentials = System.Net.CredentialCache.DefaultCredentials;

   50                         Console.WriteLine(ws.Echo(string.Format("CCR Message {0}", i), sleeptime));

   51                     }

   52                 }));

   53 

   54             Console.WriteLine("Done!");

   55             Console.ReadKey();

   56 

   57 

   58         }

Results:

traditional sequential test
Seq Message 0
Seq Message 1
Seq Message 2
Seq Message 3
Seq Message 4
traditional Async Model test
CCR test
Done!
CCR Message 0
CCR Message 1
CCR Message 2
CCR Message 3
Async Message 1
Async Message 2
Async Message 0
Async Message 3
Async Message 4
CCR Message 4

Posted by sweisfeld | with no comments
Filed under:

Using the CCR for Line of Business Applications

For fun I have been playing around with Microsoft Robotics studio (http://microsoft.com/robotics) for a long time now and I have listened to Microsoft’s George Chrysanthakopoulos tell us how cool the CCR was in just about every webcast. Well I have decided to see if I can use the CCR in a regular business application and eliminate some of the pains of writing multithreaded code.

To that end I started with a simple problem, calculating Fibonacci numbers, and like any good developer I started with an easy to implement sequential algorithm. Now that I could sequentially calculate the numbers I wanted to see if I can use the CCR to calculate the same results. This required creation of a new execute method, but note that I was able to reuse the code that I wrote to calculate 1 Fibonacci number, the only thing I am rewriting is the test harness. Finally I rewrote the code using a traditional threading model.

Calculating 10 Fibonacci numbers sequentially took about 13.7 seconds on my dual core laptop, but as one would expect only one of my cores was actually working the other one just sat there doing nothing. On the other hand when processing the same set of numbers with both the CCR or the traditional threading model it took about 7.3 seconds. This is due to the fact that now I was able to use both cores of my computer.

I know what you are saying, self, why use the CCR I could just use traditional threading techniques. IMHO the major benefit you get with the use of the CCR is that the delta between the sequential code you write and the CCR enabled code you write is much smaller.

The CCR makes heavy use of queuing logic. So when you have work to be performed you just shove it in a queue and attach a receive arbiter to tell the CCR what to do with each work item (message). The CCR takes care of all the plumbing required to schedule and coordinate each item.

When starting to work with the CCR I strongly recommend reading the following articles. All of witch I have shamelessly borrowed ideas from.

The Code

This is my entry point where I generate some random numbers and then pass them to each of the test harnesses to get processed.

    1             //Generate random number to calculate Fibonacci for

    2             int[] fibonacciCalculations = new int[10];

    3             Random r = new Random();

    4             for(int i = 0; i < fibonacciCalculations.Length; i++)

    5             {

    6                 fibonacciCalculationsIdea = r.Next(30, 40);

    7             }

    8 

    9             SequentialExample.Execute(fibonacciCalculations);

   10             ThreadPoolExample.Execute(fibonacciCalculations);

   11             CcrExample.Execute(fibonacciCalculations);

   12 

   13             Console.WriteLine("Done!");

   14             Console.ReadKey();

Sequential Test Harness

    1     /// <summary>

    2     /// Method used to exercise the sequential algorithm

    3     /// </summary>

    4     public class SequentialExample

    5     {

    6         public static void Execute(int[] fibonacciCalculations)

    7         {

    8             DateTime start = DateTime.Now;

    9 

   10             //iterate over the collection, calculate and display the results

   11             for (int i = 0; i < fibonacciCalculations.Length; i++)

   12             {

   13                 SequentialFibonacci f = new SequentialFibonacci(fibonacciCalculationsIdea);

   14                 f.Calculate();

   15                 Console.WriteLine("Answer: {0}", f.FibOfN);

   16             }

   17 

   18             //Display the execution time

   19             TimeSpan runtime = DateTime.Now.Subtract(start);

   20             Console.WriteLine("Sequential in {0} milliseconds.", runtime.TotalMilliseconds);

   21         }

   22     }

   23 

   24     /// <summary>

   25     /// Calculate a given Fibonacci number

   26     /// </summary>

   27     public class SequentialFibonacci

   28     {

   29         /// <summary>

   30         /// Default constructor

   31         /// </summary>

   32         /// <param name="n"></param>

   33         public SequentialFibonacci(int n)

   34         {

   35             _n = n;

   36         }

   37 

   38         /// <summary>

   39         /// Recursive method that calculates the Nth Fibonacci number.

   40         /// </summary>

   41         /// <param name="n"></param>

   42         /// <returns></returns>

   43         private int Calculate(int n)

   44         {

   45             if (n <= 1)

   46             {

   47                 return n;

   48             }

   49 

   50             return Calculate(n - 1) + Calculate(n - 2);

   51         }

   52 

   53         /// <summary>

   54         /// Calculate the fibonacci number for me

   55         /// </summary>

   56         public void Calculate()

   57         {

   58             _fibOfN = Calculate(_n);

   59         }

   60 

   61         public int N { get { return _n; } }

   62         private int _n;

   63 

   64         public int FibOfN { get { return _fibOfN; } }

   65         private int _fibOfN;

   66     }

CCR Test Harness

    1 public class CcrExample

    2     {

    3         public static void Execute(int[] fibonacciCalculations)

    4         {

    5             DateTime start = DateTime.Now;

    6 

    7             //Create the queues

    8             DispatcherQueue dq = new DispatcherQueue();

    9             Port<SequentialFibonacci> fibPort = new Port<SequentialFibonacci>();

   10             SuccessFailurePort results = new SuccessFailurePort();

   11 

   12             //Post the work to be completed

   13             for (int i = 0; i < fibonacciCalculations.Length; i++)

   14             {

   15                 fibPort.Post(new SequentialFibonacci(fibonacciCalculationsIdea));

   16             }

   17 

   18             //Tell the CCR how to proccess each work item

   19             //(scatter the work over avaiable workers)

   20             Arbiter.Activate(dq,

   21                 Arbiter.Receive(true, fibPort,

   22                 delegate(SequentialFibonacci fib)

   23                 {

   24                     try

   25                     {

   26                         fib.Calculate();

   27                         Console.WriteLine("Answer: {0}", fib.FibOfN);

   28                         results.Post(new SuccessResult());

   29                     }

   30                     catch (Exception ex)

   31                     {

   32                         results.Post(ex);

   33                     }

   34                 }));

   35 

   36             //Tell the CCR to wait tell us when it is done

   37             //(Gather up all the results)

   38             Arbiter.Activate(dq,

   39                 Arbiter.MultipleItemReceive(results, fibonacciCalculations.Length,

   40                 delegate(ICollection<SuccessResult> successes, ICollection<Exception> failures)

   41                 {

   42                     TimeSpan runtime = DateTime.Now.Subtract(start);

   43                     Console.WriteLine("CCR in {0} milliseconds.", runtime.TotalMilliseconds);

   44                 }));

   45         }

   46 

   47     }

Thread Pool Test Harness

    1     /// <summary>

    2     /// Excerpt from How to: Use a Thread Pool (C# Programming Guide)

    3     /// http://msdn2.microsoft.com/en-us/library/3dasc8as(VS.80).aspx

    4     /// </summary>

    5     public class ThreadedFibonacci

    6     {

    7         public ThreadedFibonacci(int n, ManualResetEvent doneEvent)

    8         {

    9             _n = n;

   10             _doneEvent = doneEvent;

   11         }

   12 

   13         // Wrapper method for use with thread pool.

   14         public void ThreadPoolCallback(Object threadContext)

   15         {

   16             int threadIndex = (int)threadContext;

   17             _fibOfN = Calculate(_n);

   18             Console.WriteLine("Answer: {0}", _fibOfN);

   19             _doneEvent.Set();

   20         }

   21 

   22         // Recursive method that calculates the Nth Fibonacci number.

   23         public int Calculate(int n)

   24         {

   25             if (n <= 1)

   26             {

   27                 return n;

   28             }

   29 

   30             return Calculate(n - 1) + Calculate(n - 2);

   31         }

   32 

   33         public int N { get { return _n; } }

   34         private int _n;

   35 

   36         public int FibOfN { get { return _fibOfN; } }

   37         private int _fibOfN;

   38 

   39         private ManualResetEvent _doneEvent;

   40     }

   41 

   42     public class ThreadPoolExample

   43     {

   44         public static void Execute(int[] fibonacciCalculations)

   45         {

   46             DateTime start = DateTime.Now;

   47 

   48             // One event is used for each Fibonacci object

   49             ManualResetEvent[] doneEvents = new ManualResetEvent[fibonacciCalculations.Length];

   50             ThreadedFibonacci[] fibArray = new ThreadedFibonacci[fibonacciCalculations.Length];

   51 

   52             // Configure and launch threads using ThreadPool:

   53             for (int i = 0; i < fibonacciCalculations.Length; i++)

   54             {

   55                 doneEventsIdea = new ManualResetEvent(false);

   56                 ThreadedFibonacci f = new ThreadedFibonacci(fibonacciCalculationsIdea, doneEventsIdea);

   57                 fibArrayIdea = f;

   58                 ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);

   59             }

   60 

   61             // Wait for all threads in pool to calculation...

   62             WaitHandle.WaitAll(doneEvents);

   63 

   64             TimeSpan runtime = DateTime.Now.Subtract(start);

   65             Console.WriteLine("Threaded in {0} milliseconds.", runtime.TotalMilliseconds);

   66 

   67         }

   68     }

Posted by sweisfeld | with no comments
Filed under: , ,