Jan 262015
 

Reticle with ComponentModelCache Folder

Several times in the past few months, I have experienced an error loading a solution in Visual Studio 2013 that goes something like:

“The ‘<packagename>’ package did not load correctly.”

Every time that I have had this error, the solution has been to go to the “C:\Users\<user>\AppData\Local\Microsoft\VisualStudio\12.0 folder and delete the ComponentModelCache folder.

I suspect that the contents of the cache folder get corrupted and/or out of sync when the OS shuts down unexpectedly while Visual Studio 2013 is up.  It’s annoying, but deleting the ComponentModelCache forces Visual Studio to load without the cache and fixes the problem every time.

Sep 272013
 

I have worked with GIS systems for many years now, working with both ESRI, Intergraph, and Bentley (if you count that MicroStation class I took in college) systems.  Sometimes when you are working on client-side code, it is useful to see the actually calls from the client back to the database.  One of the most useful and simple tools that I have found when working with ESRI’s ArcMap is to set up an SDE intercept.  By doing this, intercept files are generated on the client machine that contain very verbose output pertaining to every transaction with the undrelying geodatabase.  The output can be overwhelming, but it can also be very revealing.

Setting up the intercept is very easy.  You only need to add 2 environment variables to your system.  The following are the variables and their values:

  • SDEINTERCEPTLOC = c:\temp\<the subfolder you created to contain intercept files>
  • SDEINTERCEPT = crwtf

You could also set these up with a bat file if you want.

After you have set these environment variables, run ArcMap and the workflow that you want to examine.  You can then investigate the log generated to diagnose your issue.

Be sure to remove these environment variables when you are finished.  The output is very verbose and can quickly fill up your hard drive!

Sep 202013
 

The .NET Framework provides a straight-forward and fairly easy syntax to use for callbacks.  These callbacks can be used for all sorts of messaging within your system.  These messages can signal a UI event, like a button press, or they can be used to send a message to many objects serially (multicasting).

The basis for all of this communication comes from ye olden callback.  The callback is simply a method where a pointer to a function is passed and then that pointer is used to (you guessed it) call back to that function.  This works well and has for years.  However, the problem with this methodology is that it is not type-safe.  That is, the function callback is merely a pointer to a location in memory where the function resides.  There is no guarantee that the function will have the expected signature of the code doing the callback.  This is where delegates come into play in the .NET Framework.

System.Delegate is a type in the .NET Framework Class Library that is used as a type-safe wrapper for a callback.  The delegate allows the CLR to ensure that all calls through the delegate will have the proper parameters.  Further, System.Delegate is extended with the System.MulticastDelegate type to allow for callbacks to multiple clients.

Events are a special type of delegate that provide protection for event calling and for the underlying delegates invocation list.  That is, only the class that defined the class my invoke the event and subscribers are allowed to add/remove only themselves from the invocation list.  Events are commonly used with UI objects, such as buttons, grids, trees, and other controls to callback to the underlying code when the user performs an action.

Defining and using events in the .NET framework is really straight-forward.  This sample shows the 3 steps to create and use a simple event:


using System;
using System.Threading;

namespace SimpleEventsExample
{
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // This is a simple example to demonstrate events. Remember these 3 things when setting up an event:
    // 1. Create a Type derived from EventArgs to pass back information pertaining to the event.
    // 2. Create an event that passes back the EventArgs instance in the object that is to publish the event
    // 3. Subscribe to the event in the objects that are to listen to the event.
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// 1. Create a Type derived from EventArgs to pass back information pertaining to the event.
    ///
    /// This is a Type derived from EventArgs whose payload is the current time at the time of the
    /// event and the seconds that have transpired since the beginning of the run.
    internal class SecondsCountdownClockExpiredArgs : EventArgs
    {
        internal SecondsCountdownClockExpiredArgs(DateTime currentTime, int secondsEllapsedSinceStart)
        {
            CurrentTime = currentTime;
            SecondsEllapsedSinceStart = secondsEllapsedSinceStart;
        }
        internal DateTime CurrentTime { get; set; }
        internal int SecondsEllapsedSinceStart { set; get; }
    }

    /// 2. Create an event that passes back the EventArgs instance in the object that is to publish the event
    ///
    /// This is the object that will be firing the event. It will allow subscription to the event via
    /// a public event.
    internal class SecondsCountdownClock
    {
        private const int MillisecondsInASecond = 1000;
        private readonly int _timerInterval;
        private int _secondsEllapsedSinceStart;
        private readonly int _seconds;

        // Define a public event to which listeners can sign up for notification
        public event EventHandler&lt;SecondsCountdownClockExpiredArgs&gt; SecondsCountdownClockExpired;

        internal SecondsCountdownClock(int seconds)
        {
            _seconds = seconds;
            _timerInterval = seconds * MillisecondsInASecond;
        }

        // Cheesy countdown timer that wakes up and fires based on the interval entered.
        internal void StartTheCountdown()
        {
            Console.WriteLine("Seconds Countdown Clock set to expire every {0} seconds", _seconds);
            for (; ; )
            {
                Thread.Sleep(_timerInterval);
                IncrementTimer();
            }
        }

        // When the interval has been reached, this function is called. If there are subscribers to the event,
        // create a new event args class, put information in the class, and fire the event.
        private void IncrementTimer()
        {
            _secondsEllapsedSinceStart += _seconds;
            if (SecondsCountdownClockExpired != null) SecondsCountdownClockExpired(this, new SecondsCountdownClockExpiredArgs(DateTime.Now, _secondsEllapsedSinceStart));
        }
    }

    /// 3. Subscribe to the event in the objects that are to listen to the event.
    ///
    /// This observer object will subscribe to the clock event and will output information to the console
    /// about the event.
    internal class ClockObserver
    {
        internal ClockObserver(SecondsCountdownClock secondsCountdownClock)
        {
            // Subscribe to the SecondsCountdownClockExpired event
            secondsCountdownClock.SecondsCountdownClockExpired += secondsCountdownClock_SecondsCountdownClockExpired;
        }

        static void secondsCountdownClock_SecondsCountdownClockExpired(object sender, SecondsCountdownClockExpiredArgs e)
        {
            Console.WriteLine("Current Time: {0:h:mm:ss}        Seconds Ellapsed Since Start: {1}", e.CurrentTime, e.SecondsEllapsedSinceStart);
        }
    }

    /// This program is a test harness that creates the countdown clock and creates and observer to listen to clock events.
    /// After it generates the clock and observer, it kicks things off by starting the clock.
    class Program
    {
        static void Main(string[] args)
        {
            // Create the clock that will publish clock events
            var seconds = Convert.ToInt16(args[0]);
            var theSecondsCountdownClock = new SecondsCountdownClock(seconds);

            // Create the observer that will listen to clock events and pass the clock pointer to its constructor
            new ClockObserver(theSecondsCountdownClock);

            // Kick off the clock
            theSecondsCountdownClock.StartTheCountdown();
        }
    }
}

Here is the output:

Output from the Seconds Countdown Clock - Demonstrating Events

Output from the Seconds Countdown Clock – Demonstrating Events

Although this sample isn’t very complicated, it is interesting to see what is going on under the covers with the Event type.  The Event type is really a special type of Delegate, which can be seen when examining the intermediate language using the ILDASM.exe tool.  A cursory look at the SimpleEventsExample.SecondsCountdownClock type shows the add and remove methods for the event:

ILdasm With Event Add and Remove

ILdasm With Event Add and Remove

Now look at the deconstruction of the add_SecondsCountdownClockExpired into IL:

Intermediate Language Showing Delete Combine

Intermediate Language Showing Delete Combine

You can see from the ILDASM output on line IL_000b that System.Delegate::Combine is the underlying mechanism used for adding to the event listener.  Further, looking at the IL for remove shows the underlying delegate remove.

Could you use a Delegate type for this?  Yes, you could, but the Event type is particularly designed for this sort of work.  It can only be raised in the class in which it was defined and it protects the invocation list (the list in the underlying delegate class) from being modified arbitrarily, which protects your code and makes for more robust software.

Sep 032013
 

I have been doing a little research on regular expression support in the .NET framework and have been impressed with my findings.  As a developer, regular expressions are a very useful tool to keep in the arsenal.  They can help programs efficiently search text and they can be used to validate input (think phone numbers or email addresses, among other things).

Two great sources of information for expression syntax are regular-expressions.info and MSDN.  These two sources help make sense of the metacharacters, escapes, anchors, groups, and other artifacts of a well-formed expression.

The syntax for searching a string using the .NET System.Text.RegularExpressions.Regex class, is very straight forward and the class seems very efficient when compared with other string search methods.  If you drop the following into a console application, you can compare the time needed to find the string “simple text” in the string represented by the “ipsum” string variable.  In this example, I generated the ipsum variable using the itools Lorem Ipsum generator.  I generated a single string 250,000 words long.


var ipsum = //generate a large string, perhaps using the itools Lorem Ipsum generator and embed "simple text" within the string

var stopwatch = new Stopwatch();

Regex RegexSearch = new Regex("simple text", RegexOptions.None);
stopwatch.Restart();
for (int i = 0; i < 1000; i++)
{
    RegexSearch.IsMatch(ipsum);
}
stopwatch.Stop();
Console.WriteLine("Ellapsed time with Non-compiled Regex: " + stopwatch.ElapsedMilliseconds);

Regex CompiledRegexSearch = new Regex("simple text", RegexOptions.Compiled);
stopwatch.Restart();
for (int i = 0; i < 1000; i++)
{
    CompiledRegexSearch.IsMatch(ipsum);
}
stopwatch.Stop();
Console.WriteLine("Ellapsed time with Compiled Regex: " + stopwatch.ElapsedMilliseconds);

stopwatch.Restart();
for (int i = 0; i < 1000; i++)
{
    ipsum.Contains("simple text");
}
stopwatch.Stop();
Console.WriteLine("Ellapsed time with Contains: " + stopwatch.ElapsedMilliseconds);

// Display times
Console.ReadLine();

The run times were pretty telling.  As you can see from this output, when searching a string with 250,000 word of random length, the non-compiled regex search was much faster:

elapsedtime

Writing regular expressions can be complicated but there are some really useful tools for use in their generation.  The defacto tool right now seems to be RegexBuddy (for a $40 license fee).  Also, Roy Osherove has several regular expression tools available at his website.  Finally, you can search for community submitted expressions at regexlib.com, where there are many, many examples from which to choose.

Your mileage (and mine) may vary from project to project, but using the Regex class to dig through large amounts of text is definitely worth considering.

Aug 032013
 

As a developer (and a power user), I find myself annoyed at the User Account Control (UAC) in Windows.  It prompts.  It nags.  It mothers.  On my development machine and VMs, in particular, I find that I want to completely disable UAC.  This allows me to run scripts and utilities in batch files and in post-build steps without interruption and grief.   To accomplish this, I run the following .reg file to directly update the UAC keys in the Windows registry:


Windows Registry Editor Version 5.00

; Disable User Account Control
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableLUA"=dword:00000000
"ConsentPromptBehaviorAdmin"=dword:00000002
"ConsentPromptBehaviorUser"=dword:00000001

; Permanently disable User Account Control
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\luafv]
"Start"=dword:00000004

All you have to do is put this into a text document named admin.reg, run it, and allow the modifications to the registry.  You will then have to restart.  When you have gotten this right, you can see right at the top of Visual Studio in the title that you are in Administrator mode, which give you unfettered access to all manner of goodness:

VSAdministratorMode

One other trick that you can do (if your IT shop changes the settings back by default – and they wouldn’t do that if they knew this was a development box, right?) is put this in your machine startup.  That way, you always reset after you reboot.

We could debate the finer points of UAC here and make all sorts of arguments as to why you should leave it on.  You should only use this reg file if you really know what you are doing and really need to have open access to your Windows GAC and registry.