Archive for the ‘C#’ Category

Friday, April 5th, 2013

This picks up with the code generation series. See other posts:

In this post we will be using project templates for code generation. Project templates are great when you are going to create many projects with similar boilerplate type code. For example if there is a plugin architecture and each plugin has one (or many) interfaces that it must implement.

In order to get started create a new project inside a solution. Write all the boilerplate code that is needed. Use the Template Parameters in the boilerplate code to make replacements. Note: it’s okay if the project doesn’t compile after adding template parameters. Make sure to setup any project specific build events, assembly references, output paths, etc. inside the project.


/*************************
* File: $safeprojectname$Plugin.cs
* Author: $username$
* Created: $time$
************************/

using Main;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace My.Plugins.Plugin.$safeprojectname$
{
///

/// Plugin: $projectname$
///

public class $safeprojectname$Plugin : IPluginInterface
{
///

/// Does work for the plugin
///

void IPluginInterface.DoWork()
{
// TODO: This MUST be implemented
throw new NotImplementedException();
}

///

/// User visible description of $safeprojectname$
///

///
string IPluginInterface.GetDefaultInfo()
{
return "Plugin ($safeprojectname$) created by $username$";
}

///

/// Returns true when the plugin is ready to do work
///

///
bool IPluginInterface.ReadyToGo()
{
return false;
}
}
}

After the boilerplate code is in go to File > Export Template…

ExportTemplate

This will bring up the “Export Template Wizard”. Make sure to select the project with the boilerplate code and click next.

ExportTemplateWizard1

The next page of the wizard allows some customization of the project name. Make sure to automatically import into visual studio.

ExportTemplateWizard2

That it. Write code once, reuse multiple times. To test out the new project template go to New > Project in Visual Studio. Since the project was automatically imported the new project template is available.

NewProject

The new project will have the file(s) specified with all the template parameters filled in:


/*************************
* File: My_Plugin_Template1Plugin.cs
* Author: Sirchris
* Created: 3/28/2013 6:52:06 AM
************************/

using Main;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace My.Plugins.Plugin.My_Plugin_Template1
{
///

/// Plugin: My Plugin Template1
///

public class My_Plugin_Template1Plugin : IPluginInterface
{
///

/// Does work for the plugin
///

void IPluginInterface.DoWork()
{
// TODO: This MUST be implemented
throw new NotImplementedException();
}

///

/// User visible description of My_Plugin_Template1
///

///
string IPluginInterface.GetDefaultInfo()
{
return "Plugin (My_Plugin_Template1) created by Sirchris";
}

///

/// Returns true when the plugin is ready to do work
///

///
bool IPluginInterface.ReadyToGo()
{
return false;
}
}
}

That’s a quick bear minimum of what can be done with project templates. Project templates can package up any set of files. In the exported template created look at the vstemplate file. There you can start to get a feel for some of the additional items that could be accomplished with templates. Make sure to look at the VSTemplate section on the MSDN.

Here is the vstemplate file created from this simple example




My Plugin Template
This is to create plugins faster
CSharp


1000
true
My Plugin Template
true
Enabled
true
__TemplateIcon.ico



Class1.cs

AssemblyInfo.cs




This is one of the simplest (and powerful) ways to get started with code generation. Keep them mind next time creating multiple project that are similar in nature. There are still two more examples of code generation coming up.

Tuesday, February 19th, 2013

One of the most vivid memories I have from reading the “The Pragmatic Programmer” is the tidbit about code generation it felt like my eyes were opened to this new and exotic world. All of a sudden the DRY principle had a new weapon (to be fair I think this was the point of that section of “The Pragmatic Programmer”). Up until that point I never thought about writing a code generator.

The biggest reason for amazement was that at the time I was in the middle of developing a Windows service to kick off Microsoft Office automation tasks. I came up with a decent pattern for spinning up an external program, doing work, and ending the external process. There was retry logic with a WatchDog that added some reliability to an inherently unreliable task. The problem was that the pattern was not abstracted very well (if I was solving the problem today I would have gone for a completely different pattern, probably implementing something more like CQRS like the eMoney Nexus; live and learn). In order to keep DRY I needed to

  1. Rewrite my service (that I just demoed as working) with better encapsulation or
  2. Use code generation!

I opted for code generation.

From memory the pseudocode for the basic pattern that I wanted to reuse for different external programs:


// Initialize the office process
private Process word = new Process(...);
public void DoWork(string method)
{
// Start up the office program
word.Start();

// Spin up the watch dog
ThreadPool.QueueUserWorkItem(new WaitCallback(Watchdog, word));

// Find the method the caller wants to invoke via reflection
MethodInfo m = this.GetType().GetMember(method)[0];
m.Invoke(this, null);
}

static void ThreadProc(Watchdog stateInfo)
{
// waits for a timeout, then check process state
// if process is still running first try to stop
// the process, if that doesn't work try to kill
// the process. Then check to see if the worker
// thread is still around, and tell it to quit
// as a last resort use Thread.Abort()
}

Basically the pattern started an external program, started a watchdog, then called a method via reflection. Anytime somebody wanted to write a new task for the external program to do they would just need to write a new method in the class and call DoWork with the name of their method. It worked great when dealing with the same process. The issue was when wanting to use excel, or acrobat, or any other external program this whole pattern would need to be reimplemented with the logic that knew how to spin up that particular program, and have method that worked with that program as well.

What I came up with was this whole pattern could be injected into the class as compile time. I changed the basic files to look like this:


private Process word = new Process(...);
public void DoWork(string method) { /***** DOWORK *****/ }

This allowed anybody writing a method inside the class to still get IntelliSense on the object they wanted to work with, and they could still call DoWork. The rest of the pattern I moved to an external console program that knew how to open the class file, find the “public void DoWork(string method) { /***** DOWORK *****/ }” string and drop in custom code per external process. Something like this:


private static readonly string wordWatchDog = @"
private Process word = new Process(...);
public void DoWork(string method)
{
// Start up the office program
word.Start();

// Spin up the watch dog
ThreadPool.QueueUserWorkItem(new WaitCallback(Watchdog, word));

// Find the method the caller wants to invoke via reflection
MethodInfo m = this.GetType().GetMember(method)[0];
m.Invoke(this, null);
}

static void ThreadProc(Watchdog stateInfo)
{
// waits for a timeout, then check process state
// if process is still running first try to stop
// the process, if that doesn't work try to kill
// the process. Then check to see if the worker
// thread is still around, and tell it to quit
// as a last resort use Thread.Abort()
}"
private static readonly magicString = "public void DoWork(string method) { /***** DOWORK *****/ }";
public void UpdateWordDotCS()
{
string wordDotCSAsString = ReadWordFile();
int magicStringStart = wordDotCSAsString.IndexOf(magicString);
using (FileStream fs = File.Open(wordDotCSFile, FileMode.Create))
{
byte[] file = ASCII.ASCIIEncoding.GetBytes(wordDotCSAsString);
// Write beginning of file
fs.Write(file, 0, magicStringStart);

// Inject our custom code
byte[] customCode = ASCII.ASCIIEncoding.GetBytes(wordWatchDog);
fs.Write(customCode, 0, customCode.Length);

// Write beginning end file
fs.Write(file, magicStringStart + magicString.Length, file.Length - magicStringStart - magicString.Length);
}
}

Then our release build process was able to first call the console program that did the code generation before it started to build the actual solution.

This first foray into code generation while crude cemented code generation as a tool in my toolbox of how to get stuff done. Since this first pass I went on to make a few more code generators.

  • A custom C# project templates with default code.
  • A program that reads a DB and creates C# classes to populate the tables.
  • An app that could read a copy/pasted table for a spec on how to read a 3rd party file and generate a class that would allow the 3rd party file to be serialized into our class.

None of these generators were particularly difficult to write and the pay off in terms of productivity was noticeable. Which makes me wonder why I don’t see more people writing generators. My theory is twofold, first I think code generation just does not come to people’s mind (which is odd since 99% of the coding we do is to simplify other work, why not simplify our own coding) and second I think the term ‘code generation’ sounds scary to people.

My next few posts will go into more details on the aforementioned code generators to illustrate how they really are not scary, and to show how there is more than one way to generate code.

Monday, September 10th, 2012

Before .NET 4 the recommended way to create a new worker item thread was using the thread pool to queue up a work item.

ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));

private void DoWork(object state)
{
Console.WriteLine("Thread {0} doing work",
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep((new Random()).Next(5, 5000));
Console.WriteLine("Thread {0} DONE work",
Thread.CurrentThread.ManagedThreadId);
}

There is nothing wrong with continuing to use the ThreadPool pattern to queue up worker thread. In fact using this pattern gets a performance boost you can see with just the enhancements Microsoft added to the ThreadPool in .NET 4. However .NET 4 also contains a whole set of features to facilitate parallel programming via the Tasks namespace. I would not recommend switching existing code to use the new features for the sake of using new feature. For the new code however it is worth taking a look to see if any of the new features would be worth using. Using tasks we could queue up worker threads in a similar matter.

new Task(DoWork, null).Start();

private void DoWork(object state)
{
Console.WriteLine("Thread {0} doing work",
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep((new Random()).Next(5, 5000));
Console.WriteLine("Thread {0} DONE work",
Thread.CurrentThread.ManagedThreadId);
}

One line code change, functionally it seems to work the same, and it is using a newer paradigm. Done right? Just because it’s newer doesn’t mean it’s better. Let’s take a look ‘under the hood’ to really see what they differences are between the two code block above.

When talking about ‘under the hood’ with .NET that basically is a code phrase for ‘opening up Reflector’. Taking a look at what actually happens when we call ThreadPool.QueueWorkerItem we can boil it down to a fairly straight forward sequence of events.

  1. Ensures that the ThreadPool VM is initialized (calls into the CLR for this via a QCall)
  2. Wraps the WaitCallback inside an ExecutionContext call back. This preserves the calling state among some other minor details
  3. Queues the item onto the Global ThreadPool

The ‘meat and potatoes’ of what is being done can be done by just viewing the ThreadPool.QueueUserWorkItemHelper method.

Task.Start.Enqueue.png

At some point then the work is Dequeued by a thread. Dequeuing in .NET 4 actually has some complexities behind it with WorkStealingQueues and other magic. For now we can be contented with the fact that all ThreadPool.QueueUserWorkItem does is put a callback on a Queue for the framework to pick up at a later date.

Now what about using Tasks and Task.Start? The sequence of events is slightly more complex.

  1. Calls Task.Start with the default TaskScheduler (which is the ThreadPoolScheduler)
  2. Checks the current state of the tasks to ensure the task can be schedules
  3. QueueTask is called on the current TaskScheduler (again by default this is ThreadPoolScheduler)

That is pretty much what the Task does, now the responsibility of scheduling the task is passed to the TaskScheduler (imagine that). Taking a look the default ThreadPoolScheduler.

  1. Looks at the options passed in
    1. If TaskCreationOptions.LongRunning pass passed in the scheduler treat this a hint to create a regular .NET Thread set as a BackgroundWorker. Because user options are tied in with the state of the ThreadPoolScheduler there is no guarantee that this code path will be taken.
    2. Otherwise ThreadPool.UnsafeQueueCustomWorkItem is called to queue up the item.
      1. If the Task was started from within a Task the WorkerItem is queued up on a local ThreadPoolQueue
      2. Otherwise the Task is queued up in the Global ThreadPool – This is what happens in the code sample above

There is more logic going on up front with the Task (for a great article on what is going on I would recommend http://msdn.microsoft.com/en-us/library/dd997402.aspx). For the typical usage pattern though Task.Start will eventually call ThreadPool.UnsafeQueueCustomWorkItem.

Task.Start.png

Which then queue up the item to be dequeued by the same ThreadPool as if we used ThreadPool.QueueUserWorkItem.

So for typicalusage there will be little difference between using ThreadPool.QueueUserWorkItem and using Task.Start. However there are some subtle differences between the two. Ultimately which way you want to use is up to you. Me? I prefer using Task.Start, mostly for the flexibility it provides (plus ‘OOOH! SHINY!’).

Note: This entry also posted on tech.collectedit.com