Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

The Case For C++ In A .NET World

I am currently working with a client to bring .NET support to the FLEXnet Publisher Licensing Toolkit version 11.6. The toolkit, as shipped, is very tightly tied to the C language, and it is designed for use with client applications written in C. My client, however, wants to use the toolkit from VB.NET 2.0 applications. I set out, therefore, with a vision that stated "make FLEXnet look like .NET".

My first approach to the problem was to use P/Invoke to write a wrapper in VB.NET 2.0. This wrapper would sit just above the FLEXnet Publisher API and would wrap the function calls within a set of .NET classes that would hide the complexities of the API. With this architecture, .NET client applications would reference the .NET 2.0 wrapper, and the client calls to the wrapper would delegate the client’s method and property calls down to one or more calls to the FLEXnet Publisher API.

This initial effort was moderately, but not completely, successful. Some of the main problems with this approach had to do with the FLEXnet Publisher API’s design which mandated:

  • Explicit Pointer Casting: Calls to lc_get_attr() and lc_set_attr() require, in some cases, that the pointer used to reference the value (or its placeholder) be cast to a pointer of a specific type, which is sometimes further obscured by a typedef, such as LM_A_VAL_TYPE or LM_SHORT_PTR. Pointer casts to different target types in a single VB.NET P/Invoke scenario are problematic.
  • Macro-Based Variable Declaration and Initialization: One of the datatypes used in the call to lc_cryptstr() must be declared by a C macro called LM_CODE() and must be initialized by a C macro called LM_CODE_GEN_INIT(). These macros are found in C header files that ship with the FLEXnet Publisher API and their translation into a VB.NET environment for use with a .NET layer proved to be very difficult.

Given the discovery of the FLEXnet Publisher API’s tight coupling to C, I devised a new approach. The approach shared the vision of the first approach – namely, "to use a .NET wrapper to wrap the FLEXnet API calls into a .NET environment" – but was built using both native (unmanaged) C++ and C++/CLI (formerly known as Managed C++). The new approach involved two steps:

  1. Wrap the FLEXnet API calls into a native, unmanaged, C++ class. The methods exposed by this class would be implemented via calls into the FLEXnet API.
  2. Build a C++/CLI class that delegates its calls to an obect of the native, unmanaged C++ class.

The main advantage to this approach is that the native C++ class can make use of all of the C header files, data types, libraries and macros that ship with the FLEXnet API, thereby providing a level of programmability not possible with a 100% .NET language solution and P/Invoke. The disadvantage to this approach is one of maintenance, as it requires someone with knowledge of C++. However, the vision statement of “make FLEXnet look like .NET” can best be realized using C++, and I am a firm believer in using the right tool for the right job.

This approach proved to be much more successful, and, thanks to Visual C++’s ability to include unmanaged and managed code in the same assembly – a feature unavailable to other .NET languages – both the native C++ class and the C++/CLI class can be included in a single assembly. The assembly exposes the C++/CLI class as a standard .NET class which can be referenced from the client’s VB.NET applications. Problem solved.

Here is an example of that approach. In this example, we will wrap the FLEXnet API lc_cryptstr() with a .NET class that can be used by .NET applications. The unmanaged, native C++ class, which is the class that will call the FLEXnet API, is declared in a header file as follows:

class UnmanagedWrapper
{
public:
    UnmanagedWrapper(void);
    static int EncryptLicenseString(char * InputString, char ** OutputString);
    ~UnmanagedWrapper(void);
};

The implementation of the class performs the work that needs to take place to wrap the FLEXnet API call:

UnmanagedWrapper::UnmanagedWrapper(void)
{
}

int UnmanagedWrapper::EncryptLicenseString(char * InputString, char ** OutputString)
{
    LM_HANDLE * lm_job;
    char * errors;

    LM_CODE(code, ENCRYPTION_SEED1, ENCRYPTION_SEED2, VENDOR_KEY1, VENDOR_KEY2, VENDOR_KEY3, VENDOR_KEY4, VENDOR_KEY5);
    LM_CODE_GEN_INIT(&code);
    lc_init(NULL, VENDOR_NAME, &code, &lm_job);
    return lc_cryptstr(lm_job, InputString, OutputString, &code, LM_CRYPT_FORCE, NULL, &errors);
}

UnmanagedWrapper::~UnmanagedWrapper(void)
{
}

Now that the native C++ class is built, the C++/CLI class can be built. Its job is to simply hold a pointer to the native C++ class and delegate calls to the native C++ class:

public ref class OwnerLicensingEngine
{
private:
    UnmanagedWrapper * thisUnmanagedWrapper;

public:
    OwnerLicensingEngine()
    {
        thisUnmanagedWrapper = new UnmanagedWrapper();
    }

    String^ EncryptLicenseString(String^ Input)
    {
        IntPtr InputAsIntPtr = Marshal::StringToHGlobalAnsi(Input);
        char * InputAsString = (char *)(void *)InputAsIntPtr;
        char * OutputString;

        thisUnmanagedWrapper->EncryptLicenseString(InputAsString, &OutputString);
        String ^ StringToReturn = gcnew String(OutputString);
        Marshal::FreeHGlobal(InputAsIntPtr);
        return StringToReturn;
    }

    ~OwnerLicensingEngine()
    {
        delete thisUnmanagedWrapper;
    }
};

The private variable thisUnmanagedWrapper points to an object of the native C++ class. The object is created in the C++/CLI class constructor and destroyed in the C++/CLI class destructor. The C++/CLI’s method implementation translates data types as necessary (in the example above, .NET String objects need to be available as character pointers usable by the native C++ class), calls the appropriate native C++ method, performs any necessary cleanup, and returns. At this point, the C++/CLI class is ready to go and can be used by .NET clients, such as in this unit test:

<TestMethod()> Public Sub TestEncryptLicenseString()
    Dim TestFLEXnetObject As New OwnerLicensingEngine
    Dim Input As String
    Dim Signed As String

    Input = "FEATURE f1 JEFF 1.000 permanent uncounted HOSTID=0003ffb91c18 SIGN=""0"""
    Signed = Nothing
    Signed = TestFLEXnetObject.EncryptLicenseString(Input)
    Assert.IsNotNull(Signed)
    Assert.AreNotEqual(Input, Signed)
End Sub

It took me a while to figure out all of the compiler and linker options to get a successful build, given the mix of .NET, FLEXnet libraries, and the Visual C++ runtime. The command line for the debug builds are shown below.

The compiler command line for the debug builds is as follows:

/Od
/I "[path to FLEXnet install]\machind"
/D "WIN32"
/D "_DEBUG"
/D "_WINDLL"
/D "_UNICODE"
/D "UNICODE"
/FD
/EHa
/MDd
/Yu"stdafx.h"
/Fp"Debug\ClientLicensingEngine.pch"
/Fo"Debug\\"
/Fd"Debug\vc90.pdb"
/W3
/nologo
/c
/Zi
/clr
/TP
/errorReport:prompt
/FU "c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll"
/FU "c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
/FU "c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"

The linker command line is as follows:

/OUT:"C:\Projects\…\ClientLicensingEngine.dll"
/INCREMENTAL
/NOLOGO
/LIBPATH:"[path to FLEXnet install]\i86_n3"
/DLL
/MANIFEST
/MANIFESTFILE:"Debug\ClientLicensingEngine.dll.intermediate.manifest"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/NODEFAULTLIB
/DEBUG
/ASSEMBLYDEBUG
/PDB:"c:\Projects\…\ClientLicensingEngine.pdb"
/DYNAMICBASE
/FIXED:No
/NXCOMPAT
/MACHINE:X86
/ERRORREPORT:PROMPT
lm_new_md.obj
lmgr_md.lib
libcrvs_md.lib
libsb_md.lib
[path to FLEXnet install]\i86_n3\activation\lib\libnoact_md.lib
msvcrtd.lib
msvcmrtd.lib
mscoree.lib
oldnames.lib
kernel32.lib
user32.lib
netapi32.lib
advapi32.lib
gdi32.lib
comdlg32.lib
comctl32.lib
wsock32.lib

The compiler and linker options shown above will need to be adjusted for release builds so that the release-mode libraries are included.

If you find this solution to be elegant, don’t thank me. Thank Visual C++, which combines its support for native C with its support for .NET to provide a simple language solution to difficult problems whose problem domains are firmly rooted in a C-based API. I worked in C and C++ for many years before switching to C# and VB.NET in the summer of 2000. I didn’t look back at C++, until now, but, given the problem I faced with this project, I am grateful for its continued presence in the Visual Studio family of languages.

Use the right tool for the right job. C++ still has its place.

Posted by jefff | 0 Comments
Filed under:

Magenic Technology Summit

The first ever Magenic Technology Summit is being held on Fri Jun 20 2008 in Downers Grove near Chicago!

This is a full day of Magenic-provided training, available by invitation only to customers and potential customers of Magenic. We have lined up an impressive array of speakers and topics in two tracks, .NET development and Microsoft servers. And we have lined up two keynotes.

Our first keynote speaker is Jay Schmelzer, who is the Group Program Manager for RAD tools. This basically means he runs the teams for all the Visual Studio designers and related RAD tools. He’s an excellent good speaker and should provide some great insight into the present and future of RAD development tools from Microsoft.

Our second keynote speaker is Rockford Lhotka, Magenic’s Technology Evangelist and the creator of the very popular CSLA .NET development framework.

But more importantly, two tracks of in-depth technical content straight from the experts at Magenic. Topics covering the present and future of .NET development and key Microsoft server products. An event like this doesn’t come along every day, and shouldn’t be missed!

The event is FREE to our customers (though you will need to cover any travel costs), and includes lunch and a reception at the end of the day. We hope to see you there!

Development Track Sessions

Writing Better Code

It’s one thing to write code that will do the job in the short-term; it’s another challenge to write code that can stand the test of time. In this session, Jason Bock will show you how you can use tools and features in VS 2008 (e.g. unit testing, CodeAnalysis, Code Coverage, etc.) to assist you in making your code maintainable over time, easy to understand, and resilient to defects.

Test Driven Development with ASP.NET MVC Framework - Building better AJAX web sites!

In this session, Nermin Dibek will disprove two myths: 1) It is nearly impossible to build a Test Driven Web in ASP.NET, and 2) Building custom Ajax implementations is too hard in ASP.NET.

Super-Optimized Microsoft LINQ: Indexed Objects

In this session, Aaron Erickson will go into how developers can use indexing techniques to allow for “constant-time” queries using LINQ to Objects. The session will cover both case studies of where this technique is used in technologies such as the i4o open source project and CSLA, as well as examples of how developers can implement the technique in their own custom collections.

User Experience and Better Designer Developer Collaboration

Anthony Handley will discuss the importance of good user experience design and how tool and technologies like WPF, Silverlight and Expression Blend are helping designers collaborate better with developers.

Server Track Sessions

Microsoft Office SharePoint Server Branding

The first thing everyone wants to do to their SharePoint installation is make it not look like SharePoint. There are many levels to SharePoint branding and the deeper you go, the more work it is. In this session Michael Cummings will cover the various ways of branding SharePoint from the “I don’t know HTML” level to the “I eat C# code for breakfast” level and also show you some areas to avoid when branding and better methods of accomplishing your goal.

Dynamic Management Views Will Save Your Life

Do you ever wish you could get an X-Ray view of your sluggish SQL Server? Take the guesswork out of troubleshooting database issues by utilizing the data collected in Dynamic Management Views. In this session, Whitney Weaver will show you the tools implemented in SQL Server 2005 that give you extraordinary view into the health and well being of your database instance. Code samples will be presented around query performance, I/O utilization, index usage, and more.

Really…what is Team Foundation Server?

Team Foundation Server (TFS) has been out on the market for a couple years and there is still more confusion about it, what it does and who can benefit from it. In this session Scott Wylie will show how each member of your team, project and company can use and benefit from TFS and how it can make life much simpler when it comes to all application lifecycle tasks.

RFID: The future is now

In the movie Minority Report, we were shown a glimpse of what the future might bring. Well that future is now. With the release of BizTalk 2006 R2, we were given a powerful new tool and technology. In this session, Shawn Doty will give an overview of what RFID is, how to implement it, and how it is used.

Posted by jefff | 0 Comments

Twin Cities Code Camp Session Slides and Code Posted

I presented a talk entitled A Tour of the Parallel Extensions to the .NET Framework last Sat Apr 05 2008 at the Twin Cities Code Camp. The talk went well and I presented for about 70 minutes. Thanks to all who attended. My slide deck and code samples from the talk are available here. Feel free to grab the slides and code, and feel free to come back to me with comments or questions (like most slide decks and code samples, they may not make too much sense in isolation and may require "speaker input").

Another Case for the Declarative Programming Model

Stephen Toub has written a blog post on the Parallel Programming with .NET blog reflecting his experiences in presenting the Parallel Extensions to conference attendees. The first question he fielded, and the one I run across quite often, is this:

"This stuff looks really cool, but why do we need to modify our code to use Parallel Extensions; why can't you just automatically parallelize it for me?"

The answer, in part, is that our current imperative style of programming makes it difficult for code analysis engines to figure out what a block of code is really trying to do, thereby hampering efforts by the engine to figure out what code should be run in parallel. Doing a simple replacement of for with Parallel.For is not a good solution, because the sequential for loops might be modifying state that, when run in parallel, will cause unpredictable results, especially when working with data structures that contain thread-unsafe code (methods like List<>.Add() are not thread-safe).

Code analysis engines can do a better job of injecting optimizations such as parallelism if we write code to say what we want done (which is the declarative style of programming) rather than how we want it done (which is the imperative style of programming). If we write code that says "give me these results" rather than "execute this loop and modify these data structures", code execution engines can do a better job of optimizing executing code that is sensitive to a machine's hardware capabilities.

When LINQ was first introduced, I failed to see its benefits. After all, I thought, it was simply syntactic sugar over foreach, which is itself syntactic sugar over IEnumerable and friends ("Syntactic Sugar" would be a great band name, by the way). After reflecting on LINQ, I have recently found it to be significant not on its own merits so much as what it points to: a declarative style of programming that says "perform this action" instead of "run this code".

This model has gotten a lot of press lately, through technologies like LINQ and F#. However, this declarative style is nothing new. You have most likely been working in a declarative model for years, if not decades, and just haven't realized it. It's called SQL.

Here's what you write in SQL:

SELECT * FROM Customers WHERE State = 'MN'

Here's what you don't write in SQL:

Row [] MinnesotaRows;
Table CustomersTable = new Table("Customers");

if (CustomersTable.HasIndices == true)
{
    Index StateIndex = CustomersTable.GetIndex("State");
    MinnesotaRows = StateIndex.FindRows("MN");

}
else
{
    List<Row> RowList = new List<Row>();
    foreach(Row CurrentRow in CustomersTable.Rows)
    {
        if(CurrentRow.Column["State"].Equals("MN") == true)
            RowList.Add(CurrentRow);

    }
    MinnesotaRows = RowList.ToArray();

}

The first example is "go get this result set" and the second example is "run this code recipe". The first example abstracts the "what" from the "how" and allows the SQL engine to use whatever algorithms best suited to satisfy the results. Parallelism is just one example of an algorithm that the SQL engine may or may not employ; the original declarative-style query statement will survive any algorithm change within the engine.

I ask you to consider the declarative programming style in that light. It's not just some "new way of doing things" - it's a model that let's us developers shift focus away from somewhat-brittle algorithmic details and focusing instead on writing code that describes what we need done. With a model like that, we'll move closer to allowing code analysis tools to automatically parallelizing code, because we won't have to write algorithms that either depend upon, or exclude us from, parallelism.

Parallel For Loops with Thread Local State

A recent MSDN post contained the following code:

string[] entropy_array = { "e", "r", "t", "y", "u", "ı", "o", "p",
                     "ğ", "ü", "a", "s", "d", "f", "g", "h", "j", "k", "l",
                     "ş", "i", "z", "c", "v", "b", "n", "m", "ç", "ö", " "};

Dictionary<string, int> entropy = new Dictionary<string, int>();
     

Parallel.For(0, entropy_array.Length, i =>
{
    for (int j = 0; j < entropy_array.Length; j++)
    {
        entropy.Add(entropy_array[i] + entropy_array[j], 0);
    }
});

The author of the post, who wanted to add all two letter combinations from the letters found in the entropy_array array into the entropy dictionary, wondered why the number of elements in the dictionary varied from run to run.

The problem with the code is that the introduction of Parallel.For() brings multiple threads into the picture, and, since Dictionary<T1, T2>.Add() isn't thread safe, correctness can't be guaranteed.

Huseyin Yildiz proposed a solution to this problem. His solution involved setting up a dictionary for each thread created by Parallel.For(), letting each thread do its work, and placing the intermediate results in the thread-local dictionary. Once the thread ended, the results from the thread-local dictionary could be added to the main dictionary.

This scenario is entirely possible using one of the overloads to Parallel.For(). I'll start by posting the solution, built as a simple console application, and will spend the rest of this blog post explaining the code:

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, int> Entropy = new Dictionary<string, int>();
        string[] EntropyArray = { "e", "r", "t", "y", "u", "ı", "o", "p",
                     "ğ", "ü", "a", "s", "d", "f", "g", "h", "j", "k", "l",
                     "ş", "i", "z", "c", "v", "b", "n", "m", "ç", "ö", " "};

        Parallel.For(
            0,
            EntropyArray.Length,
            () => new Dictionary<string, int>(),
            (i, state) =>
            {
                for (int j = 0; j < EntropyArray.Length; j++)
                {
                    state.ThreadLocalState.Add(EntropyArray[i] + EntropyArray[j], 0);
                }
            },
            (SubList) =>
            {
                lock (EntropyArray)
                {
                    foreach (KeyValuePair<string, int> Pair in SubList)
                        Entropy.Add(Pair.Key, Pair.Value);
                }
            }
            );
    }
}

The overload of Parallel.For() employed here takes five parameters:

  • int fromExclusive: The zero-based index used as the start of the loop.
  • int toExclusive: The zero-based index used as the stopping point of the loop. Once the loop indexer gets to this value, processing wil stop.
  • Func<Tlocal> threadLocalSelector: A function that returns the object to be used as the thread-local object for the thread executing its piece of the total loop.
  • Action<int,ParallelState<Tlocal>> body: The action to be taken by each loop iteration.
  • Action<Tlocal> threadLocalCleanup: A function specifying cleanup code to be executed once the thread's portion of the processing has finished.

The fromExclusive parameter in my example is simple:

    0,

The toExclusive parameter in my example is also simple:

    EntropyArray.Length,

The threadLocalSelector parameter is a function body that creates a new string-to-int dictionary to be used as the thread-local object for the thread:

    () => new Dictionary<string, int>(),

The body parameter performs the processing, placing the results in the thread-local dictionary:

    (i, state) =>
    {
        for (int j = 0; j < EntropyArray.Length; j++)
        {
            state.ThreadLocalState.Add(EntropyArray[i] + EntropyArray[j], 0);
        }
    },

The first parameter passed to the body is the loop indexer, and the second parameter is an object of type ParallelState, which has a property called ThreadLocalState containing the thread-local object.

Finally, the threadLocalCleanup parameter specifies the code run when the thread has finished its execution:

    (SubList) =>
    {
        lock (EntropyArray)
        {
            foreach (KeyValuePair<string, int> Pair in SubList)
                Entropy.Add(Pair.Key, Pair.Value);
        }
    }

This code, which is called with the thread-local object as a parameter, adds the items in the thread-local list to the main list. Because the Add() method is not thread safe, the code block is locked.

The caveat to all of this is that this code, with its copying and object allocations, may not be as performant as a sequential algorithm, given the small input set. Given a larger input set, however, the performance gains will most likely outweigh the additional overhead.

Parallel.ForEach Sample: Fibonacci Numbers

A post on the MSDN Forums recently asked for a sample illustrating the use of Parallel.ForEach(), so I decided to build up a small Fibonacci number calculation sample over my lunch hour. Here it is:

class Program
{
    //---------------------------------------------------------------------
    //---------------------------------------------------------------------
    static void Main(string[] args)
    {
        //-----------------------------------------------------------------
        // Create a new list and add random integers to it.
        //-----------------------------------------------------------------
        List<int> Integers = new List<int>(20);
        Random RandomIntGenerator = new Random(DateTime.Now.Millisecond);
        for(i = 0; i < Integers.Capacity; i++)

            Integers.Add(RandomIntGenerator.Next(1, 20));
        //-----------------------------------------------------------------
        // Iterate over the list in a parallel fashion and calculate
        // Fibonacci numbers for each of the list items.
        //-----------------------------------------------------------------
        Parallel.ForEach<int>(Integers, (i) =>
            {
                Console.WriteLine("[{0}] F({1}) = {2}", Thread.CurrentThread.Name, i, CalculateFibonacciNumber(i));
            });
    }

    //---------------------------------------------------------------------
    //---------------------------------------------------------------------
    static int CalculateFibonacciNumber(int Value)
    {
        Thread.Sleep(1);
        if (Value < 0)
            throw new ArgumentOutOfRangeException("CalculateFibonacciNumber");
        if (Value == 0)
            return 0;
        if (Value == 1)
            return 1;
        int Fibonacci = CalculateFibonacciNumber(Value - 1) + CalculateFibonacciNumber(Value - 2);
        return Fibonacci;
    }
}

The output (which will differ every time due to the randomness built into the sample) will look something like this: 

[Worker 2] F(1) = 1
[Worker 2] F(10) = 55
[Worker 2] F(2) = 1
[Worker 2] F(11) = 89
[Worker 3] F(13) = 233
[Worker 3] F(10) = 55
[Worker 3] F(1) = 1
[Worker 1] F(14) = 377
[Worker 2] F(15) = 610
[Worker 3] F(15) = 610
[Worker 2] F(13) = 233
[Worker 2] F(9) = 34
[Worker 2] F(5) = 5
[Worker 1] F(17) = 1597
[Worker 1] F(9) = 34
[Worker 1] F(13) = 233
[Worker 1] F(13) = 233
[Worker 1] F(10) = 55
[Worker 1] F(11) = 89
[Worker 1] F(7) = 13

Originally, I loaded the input list using parallel code:

//-----------------------------------------------------------------
// Create a new list and add random integers to it.
//-----------------------------------------------------------------
List<int> Integers = new List<int>(20);
Random RandomIntGenerator = new Random(DateTime.Now.Millisecond);
Parallel.For(0, Integers.Capacity, (i) =>
    {
        Integers.Add(RandomIntGenerator.Next(1, 20));
    });

However, Stephen Toub noted three issues with this approach:

  • The Random class is not thread-safe and could be misused when multiple threads are involved.
  • The List<>.Add() method is not thread-safe and could be misused when multiple threads are involved.
  • So little work is being done in the loop that the overhead of the parallelization infrastructure may actually cause the code to be less performant than a sequential loop.

Other notes:

  • I have included the worker thread name in the output so that I could see that parallelism was taking effect and that different threads were performing different amounts of processing.
  • The Thread.Sleep(1) call in the beginning of the Fibonacci implementation is there just to put the current thread to sleep so the operating system scheduler could switch processing to another thread. This helps force parallelism on my single-core virtual development machine.
  • The implementation of the Fibonacci algorithm is not ideal, but is good enough for a small sample application.

Dual-Threaded TaskManager on a Single Core

I just ran the following code on a single core machine:

static void Main(string[] args)
{
    Task Task1;
    Task Task2;
    Action<object> MainAction;
    TaskManagerPolicy CurrentPolicy;

    MainAction = ActionMethod;
    CurrentPolicy = new TaskManagerPolicy(2, 2);
    TaskManager CurrentTaskManager = new TaskManager(CurrentPolicy);
    Task1 = Task.Create(MainAction, CurrentTaskManager);
    Task2 = Task.Create(MainAction, CurrentTaskManager);
    Task1.Wait();
    Task2.Wait();
}

static void ActionMethod(object o)
{
    Console.WriteLine("Thread Name: {0}", Thread.CurrentThread.Name);
}

My intent with this code was to see the two tasks executing on separate threads. Since the default TaskManager uses one thread per processor, and since I was running the code on a single core machine, the default TaskManager would have executed both tasks on a single thread. In the code above, I used a TaskManagerPolicy object to specify a minimum of two threads and an ideal thread count of two, and I constructed a new TaskManager using that policy.

Imagine my surprise when the output was as follows:

Thread Name: Worker 1
Thread Name: Worker 1

Both tasks ran on the same thread! This wasn't what I was expecting, especially since I explicitly asked for two threads in my task manager policy object.

Then, I modified the ActionMethod to put the task to sleep:

static void ActionMethod(object o)
{
    Console.WriteLine("Thread Name: {0}", Thread.CurrentThread.Name);
    Thread.Sleep(5000);

}

Then, my output changed to what I was expecting:

Thread Name: Worker 1
Thread Name: Worker 2

What was the difference? The difference has to do with issues with threads and blocking.

When tasks are created, they are placed in a work queue that is managed by the associated TaskManager object. The TaskManager object also creates the requested two worker threads. Adding the tasks to the TaskManager object's work queue signals one of the worker threads that an item is available and the worker thread begins running the task. Since there is, in my situation, only one core, the TaskManager object has no way of notifying the second worker thread of the existence of Task2, until Task1 is finished or blocks. Without the call to Thread.Sleep(), as in my first example, Worker Thread 1 finishes Task1 and the TaskManager object signals Worker Thread 1 again to start Task2.

With the call to Thread.Sleep(), as in my second example, Worker Thread 1 blocks, and the operating system scheduler switches to a runable thread. The TaskManager object can now signal Worker Thread 2 to start Task2.

Aggregated Exceptions

Running code in parallel raises the possibility that more than one exception may be thrown, in parallel, from a single body of code. This means that code written to use the Parallel Extensions needs to account for that possibility.

Consider the following sequential, imperative for loop:

for(i = 0; i < 1000; i++)
{
    if ((i % 2) != 0)
        throw new NotSupportedException();
}

This loop is set to execute 1,000 iterations of a loop. When the iteration counter is not evenly divisible by two, the code throws an exception. Given the sequential nature of this loop, the first (and only) exception will be thrown when the value of i is 1. At that point, the loop will stop and the stack will unwind to the first available handler for the exception. No magic here - that's straightforward enough. One exception is all that is available, and all that is needed.

But what will happen when this loop runs in parallel? Consider this parallel version of the same algorithm:

Parallel.For(0, 1000, i =>
    {
        if ((i % 2) != 0)
            throw new NotSupportedException();
    }
);

Multiple threads will be spun up to handle this algorithm, which means that multiple threads will be throwing instances of the NotSupportedException class in parallel. How will you catch them all?

The good news is that you don't have to. The Parallel Extensions supports a new exception type called System.Threading.AggregateException, that aggregates all exceptions thrown from threads spun up to do parallel work. This gives you a single exception to catch, which means that you can write a try/catch block in the same manner that you do today, without having to worry about catching multiple exceptions raised from threads that you didn't even directly spin up in the first place.

The AggregateException class contains a property called InnerExceptions, which is of type System.Collections.ObjectModel.ReadOnlyCollection<Exception>. This collection, as you might guess, contains all of the exception objects thrown from various threads that were spun up to do work in parallel.

Given that, you can write an exception management block for that same parallel loop using something like this:

try
{
    Parallel.For(0, 1000, i =>
        {
            if ((i % 2) != 0)
                throw new NotSupportedException();
        }
    );
}
catch (System.Threading.AggregateException AggEx)
{
    Console.WriteLine("Inner Exceptions: {0}", AggEx.InnerExceptions.Count);
    for (int i = 0; i < AggEx.InnerExceptions.Count; i++)
        Console.WriteLine("* {0}: {1}", i, AggEx.InnerExceptions[i].GetType().ToString());
}

When I run this code on my Dell Latitude D620 dual-core laptop, I get the following output:

Inner Exceptions: 2
* 0: System.NotSupportedException
* 1: System.NotSupportedException

PFX Dec 2007 CTP: Executing Tasks Sequentially

An MSDN forum post from a couple of months ago (OK, so I am slow) asked if it was possible to schedule a task for execution after a previous task executed. Stephen Toub noted that handling the Completed event on a Task object would be the key to making such a design possible.

I have taken Stephen's design pattern and have implemented it in code. My fairly straightforward code sample is here in a ZIP file that contains a Visual Studio 2008 solution that illustrates the pattern. The driving force in the sample is in my implementation of a simple TaskCoordinator replacement that implements a new method called WaitAllSequential():

Post2674628.TaskCoordinator tc = new Post2674628.TaskCoordinator();
tc.WaitAllSequential(
new Task[] { Task1, Task2, Task3 });

Unlike the static TaskCoordinator class that ships with the Dec 2007 CTP of the Parallel Extensions to the .NET Framework, my TaskCoordinator needs an object instance with which to work. I arrived at this conclusion after diving, for a bit, into extension methods. My original hope was to add a static extension method onto the existing TaskCoordinator class to handle the sequential task exection:

TaskCoordinator.WaitAllSequential(new Task[] { Task1, Task2, Task3 });

This is because C# (and, I presume, VB.NET) does not the authoring support static extension methods (this is discussed further in another MSDN forum post). This design would match nicely with the existing design of WaitAll():

TaskCoordinator.WaitAll(new Task[] { t1, t2, t3 });

But, without support for static extension methods, I'm left with requiring an instance. However, the TaskCoordinator class is an abstract class, so I can't write:

TaskCoordinator tc = new TaskCoordinator();
tc.WaitAllSequential(new Task[] { t1, t2, t3 });

Furthermore, I can't use a Task object, even though Task derives from TaskCoordinator:

TaskCoordinator tc = new Task();
tc.WaitAllSequential(new Task[] { t1, t2, t3 });

This is because the Task class does not have a parameterless constructor, and it seems like overkill to construct a valid Task object just to get all of this to work. Given all of this, then, the code design simply reverts to implementing a static class called TaskCoordinator in a different namespace.

Twin Cities Code Camp: Spring 2008

I wanted to put out an advertisement for the Spring 2008 session of the Twin Cities Code Camp. You can go here for a list of sessions. I will be speaking about the Parallel Extensions to the .NET Framework, and many other excellent sessions are planned as well. For more information about the Twin Cities Code Camp, go here.

 See you on April 5!

A WPF-Based NFA Viewer for Sotue

My work in building NFAs from regular expressions is nearly complete; many constructs are supported. I have a variety of unit tests built to test the construction of NFAs for various constructs (such as the OR operator in a regular expression of "a|b"), and those tests are passing. I thought that it might be interesting to visualize these NFAs, so I have constructed a simple viewer using Windows Presentation Foundation (WPF):

 Sotue NFA Viewer: May 14 2007

All in all, WPF has made this task pretty simple. With WPF, I have been able to do the following:

  • draw states with the WPF Ellipse class
  • use radial gradient shadings to give a 3D-ish look to the state ellipses (with the NFA's end state shaded in green)
  • draw transition lines between shapes with the WPF Line class
  • provide tool tips for the states that list the state's ID
  • provide tool tips for the state transition lines that list the destination state for the transition line and the character (if applicable) that will move the machine from the source state to the destination state

This was a good exercise for working with WPF using C#. Since the NFAs are generated on the fly by the Sotue engine, the NFA cannot be drawn in XAML by a designer but instead must be drawn on the fly with C# codebehind goodness. In general, this WPF-based approach was easier than performing the same task with GDI+ -- more importantly, I got a chance to work with WPF.

I've got more work to do on the viewer, such as scaling the NFA to fit the canvas' contents, and getting arrowheads rotated properly for state transition lines that are not horizontal, and better state placement decisions for layout, but I'm off to a fair enough start.

Posted by jefff | 0 Comments
Filed under: ,

Fixing The TF30255 Error During TFS Project Creation

Over the last few days, I have been struggling with creating a new project on my TFS installation.  The project creation operation would fail about 85% of the way through the process with an error which read TF30255: Error uploading report : Work Item With Tasks. Apparently, TFS was attempting to upload report templates to SQL Server 2005 Reporting Services and was failing.

I was finally able to resolve the issue today and wanted to document my fixes:

  • add a role called RSExecRole to the master database
  • add a role called RSExecRole to the msdb database
  • add permissions to the "Securables" section of the RSExecRole in the master database
    • add the execute permisssion for the extended stored procedure called xp_sqlagent_notify
    • add the execute permisssion for the extended stored procedure called xp_sqlagent_enum_jobs
  • add permissions to the "Securables" section of the RSExecRole in the msdb database
    • add the execute permisssion for the stored procedure called sp_add_category
    • add the execute permisssion for the stored procedure called sp_verify_job_identifiers
    • add the select permission for the table called sysjobs

I'm guessing this was something I missed in the TFS Installation Guide. I really need to stop being lazy and read before I install. Thanks goes to this post for helping me out on this thorny problem.

 Now I can create a TFS project for Sotue ...

 

Posted by jefff | 2 Comments
Filed under:

TFS Installations and SQL Server 2005 Collations

I've just installed Team Foundation Server (TFS) in a Windows 2003 Standard R2 VPC, and I can say that the biggest challenge had to do with the collation settings in the SQL Server 2005 instance used by TFS. The TFS Installation Guide mentions the importance of the correct collation, and this point is not to be underestimated.

Before TFS installs, it runs a system check to ensure that all of its prerequisites are in place. One of those checks has to do with the collation settings on the default SQL Server 2005 instance. It's important to know that TFS does not support case sensitive collation settings, nor does it support accent sensitive collation settings. My issue was that, by the time I had figured this out, I had already installed SQL Server 2005, Analysis Services, Reporting Services and Sharepoint 2.0. Worse yet, the SQL Server 2005 Management Studio does not allow you to change collation settings on a server after installation. Yikes! I was faced with uninstalling and re-installing SQL Server 2005 just to change the collation settings to make TFS happy.

Luckily, some digging found a somewhat easier answer. I had the option of reinstalling the SQL Engine and specifying the new collation during the reinstallation. I mounted the SQL Server 2005 ISO into my VPC, opened a command prompt, moved to the \Servers directory on the mounted ISO, and ran the following:

D:\Servers>start /wait setup.exe /qb INSTANCENAME=MSSQLSERVER REINSTALL=SQL_Engine REBUILDDATABASE=1 SAPWD=<SA password> SQLCOLLATION=SQL_Latin1_General_CP1_CI_AS

Voila! All better, and I avoided a full reinstall.

Note that, when you run this command, you will be detaching any existing databases. Since TFS requires Reporting Services, I had the ReportServer and ReportServerTempDB databases attached to the default SQL Server instance before I reran setup.exe from the command line, and the databases were gone after setup.exe completed. The databases are simply detached, and not deleted, and they can be re-attached with ease once setup.exe completes.

If you're going to install TFS, do yourself a favor and download the Installation Guide and follow it to the letter. It will save you heartache later on.

Posted by jefff | 0 Comments
Filed under:

NFA Generation

Lexical analysis involves searching input data for lexemes that match tokens specified as regular expressions. This is enabled by building a state machine for each token, and then running each input character through the state machines looking for matches.

 Sotue's approach to state machine generation will follow the process defined in Allen Holub's excellent, though now out of print, Compiler Design In C. This process, at a high level, is as follows:

  • Generate a non-deterministic finite automata (NFA) from a regular expression
  • Optimize the non-deterministic finite automata (NFA) into a deterministic finite automata (DFA)
  • Use the deterministic finite automata (DFA) as the state machine for input stream lexeme analysis

The Sotue engine can already parse regular expressions and I have begun work to build the NFAs from the regular expressions. I am working on supporting the following constructs in regular expressions defined in Sotue tokens:

  • OR operators (a regular expression token of a|b matches input of a or b)
  • wildcard characters (a regular expression token a.y matches input of any, amy and the agy in maygar)
  • Start-of line anchors (a regular expression token of ^and matches input of and only if the and appears at the beginning of a line)
  • End-of line anchors (a regular expression token of and$ matches input of and only if the and appears at the end of a line)
  • Inclusive character classes (a regular expression token of [A-Z] matches input matches any character in the range of A through Z, inclusive)
  • Exclusive character classes (a regular expression token of [^A-Z] matches input matches any character outside of the range of A through Z, inclusive)
  • Zero-or-more closure operators (a regular expression token of a* matches a, aa, aaa and the empty string)
  • One-or-more closure operators (a regular expression token of a+ matches a, aa, and aaa but not the empty string)
  • Zero-or-one closure operators (a regular expression token of a? matches a and the empty string but not aa and not aaa)
  • Groups (a regular expression token of (ab)* matches the grouped expression ab zero or more times)

I am now working on building NFAs for each of these situations. I am, in parallel, working on building a small WPF app that will draw out the NFA for a regular expression as a series of circled states connected by lines.

Posted by jefff | 0 Comments
Filed under:

The Sotue Vision: Lex and Yacc the .NET Way

The lex tool is defined in Wikipedia as follows:

lex is a program that generates lexical analyzers ("scanners" or "lexers"). Lex is commonly used with the yacc parser generator. Lex, originally written by Eric Schmidt and Mike Lesk, is the standard lexical analyzer generator on Unix systems, and is included in the POSIX standard. Lex reads an input stream specifying the lexical analyzer and outputs source code implementing the lexer in the C programming language.

The tool accepts an input file that describes the patterns that it needs to find in the input stream. The input file looks something like this:

/*** Definition section ***/

%{
/* C code to be copied verbatim */
#include <stdio.h>
%}

/* This tells flex to read only one input file */
%option noyywrap

%%
    /*** Rules section ***/

    /* [0-9]+ matches a string of one or more digits */
[0-9]+  {
            /* yytext is a string containing the matched text. */
            printf("Saw an integer: %s\n", yytext);
        }

.       {   /* Ignore all other characters. */   }

%%
/*** C Code section ***/

int main(void)
{
    /* Call the lexer, then quit. */
    yylex();
    return 0;
}

The lex tool generates C code that can be folded into a larger application and used to parse the application's input.

This all made sense in 1970, when Unix systems were the dominant operating system of choice for software development, and C was the dominant language of choice. But it's 2007 now, and many of us are on desktops with .NET runtimes. We're working in Unicode now, and not just ASCII. We're working in C# and VB.NET now, and not just C (in fact, we're probably not working in C much at all). Our brave new .NET world (and by "new" I mean "six and a half years old") has moved beyond cryptic input files and unmaintainable generated code and into a language-agnostic and dynamic environment. I believe that the .NET world can do better. Projects like C# Flex exist, but, in my opinion, don't go far enough. I believe that a fresh approach to lexical analysis and grammatical parsing is needed (of course, I also believe that people should stop putting two spaces after their periods when they type, so my beliefs may often be called into question).

My vision is to create a lexical analysis and grammatical parsing engine, from the ground up, designed for the .NET platform and all of its language agnostic, Unicode-aware goodness. The engine, which I have dubbed Sotue (no, the name doesn't mean anything), would provide a .NET assembly (or set of assemblies) that would contain classes that would handle all of the details. My ultra-high-level vision looks something like this:

LexicalAnalyzer MyParser = new LexicalAnalyzer();

Token NumericToken = new Token("[0-9]+");
NumericToken.OnLexemeFound += <
delegate>;
MyParser.Tokens.Add(NumericToken);

MyParser.Parse(
<input stream object implementing IStream>);

(That's a C# sample, but, since the vision is to supply a .NET assembly, the classes will support any .NET language.)

The Token class would represent an input pattern and the OnLexemeFound event would fire when data matching the token's regular expression was found in an input stream. (In lexical analysis terms, a lexeme is a string of data that matches a regular expression defined by a token; for example, a lexeme of 123 would match a token with a regular expression of [0-9]+.)

I started work on this vision once before, but its progress was hampered by all of life's little distractions. I have more time now, and I have time to re-engage. Work towards this Sotue vision is already underway, and I'll keep this blog updated with my progress.

Welcome to Sotue.

Posted by jefff | 1 Comments
Filed under: