WPF unit testing trouble with Pack URIs

|

I have been busily coding WPF and Silverlight 2 for the last couple of months, and I will be for at least a few more weeks to come; however, during this development frenzy I ran into an issue with unit testing some new code. I also found an interesting solution to the problem, which required more than a simple query by way of , so I thought I’d share the problem and the solution here, just help the boys and girls at Google out a little.

The code under test relies on certain embedded resources. Said resources are to be consumed by a WPF bootstrapped assembly; therefore each resource is embedded in the assembly by using the build type of Resource, as opposed to Embedded Resource, which in turn means each resource has to be referenced by using a Pack URI. Therein lies the rub: whenever the unit test attempted to call the code that pulled out any of resources I would get the following  UriFormatException:

System.UriFormatException was unhandled
  Message="Invalid URI: A port was expected because of there is a colon (':') present but the port could not be parsed."
  Source="System"
  StackTrace:
       at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
       at System.Uri..ctor(String uriString, UriKind uriKind)

Bugger! You can easily reproduce this error by running the following code snippet in anything other than a WPF application:

var packUri = new Uri(
    "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml",
    UriKind.Absolute);

As the test harness is not bootstrapped by a WPF application it knows absolutely nothing about Pack URIs; and in my case the System.Uri parsing code ended up trying to parse the Pack URI as if it were a Web URI, which is clearly not what I wanted and creates a situation where all roads lead to Exception City.

However, all is not lost, here is the simple solution I used for my tests:

if (!UriParser.IsKnownScheme("pack"))
{
    UriParser.Register(new GenericUriParser
        (GenericUriParserOptions.GenericAuthority), "pack", -1);
}

If you run this code before you try to parse any Pack URIs all will be well. It is worth mentioning that you need to only call this code once per process. This code registers pack as a valid scheme (in the form of pack://) and then puts all URI parsing into a generic mode, only parsing against registered schemes (which pack is now one), and that is it .. the job, as they say, is a good ‘un.

I’ve written a small test application that tests the URI parsing across threads to prove that the Register call is truly process wide, which you can download from here: PaulJ.PackUriParsing.zip

Above is a screenshot of the app .. the first call shows the parse failing, before the call to Register, then the second two calls show the exact same Pack URI being parsed successfully on two different threads (the main UI thread, and a newly created thread for the test).

I hope this helps to make for a better Google experience for someone; as usual if you have any comments, questions, flames, enhancements I would love to hear from you. In the meantime think deeply and enjoy.

Taskbar Compass: how to use NotifyIcon in WPF

|

TaskbarCompass_designThere are a number of options available ranging from a CodePlex rewrite of the whole NotifyIcon control using the native WIN32 APIs to simply reusing the Windows Forms version of the control. I did not want to take a dependency on code that I did not have to, so in this case so I went with the Windows Forms version. It has all I need, and the implementation is really simple to boot.

This is the process I followed in my WPF app:

  • Create an Icon (I use Paint.NET with this plug-in to create icons)
  • Add the new icon to your project as a resource Windows Forms style .. not as a Resource build type but as EmbeddedResource (I tend to put icons in a folder with the name Resources and then use then use the Resources tab in the projects Properties).
  • In the App class, override the OnStartup method, and then create your NotifyIcon instance:

private System.Windows.Forms.NotifyIcon notify;
...

this.notify = new System.Windows.Forms.NotifyIcon();
this.notify.Text = "Taskbar Compass";
this.notify.Icon = PaulJ.TaskbarCompass.Properties.Resources.Compass;
this.notify.Visible = true;
this.notify.ContextMenu = new System.Windows.Forms.ContextMenu(new System.Windows.Forms.MenuItem[]
{
    new System.Windows.Forms.MenuItem("Show compass", (s, e) => this.MainWindow.Show()),
    new System.Windows.Forms.MenuItem("Hide compass", (s, e) => this.MainWindow.Hide()),
    new System.Windows.Forms.MenuItem("-"),
    new System.Windows.Forms.MenuItem("Close", (s, e) => this.Shutdown())
});

  • In the App class, over the OnExit method, and then dispose the NotifyIcon; otherwise the icon will hang around after the application is closed:

if (this.notify != null)
{
    this.notify.Dispose();
}

And there you have it. I have updated the Taskbar Compass sample application (initially created in this post) to now include with a NotifyIcon, which you can download from here: TaskbarCompass.zip.

As usual if you have a comments, questions, flames, enhancements I would love to hear from you; in the meantime think deeply and enjoy.

The Taskbar Compass: how to use the SHAppBarMessage Windows API

|

Over the last couple of weeks I’ve been writing production code in both Silverlight 2 and WPF; during that development I have had a need to provide a custom notify icon in WPF, to which I chose to the WinForms version as opposed to the myriad of versions available on Codeplex, but that’s a whole different post.

One issue that I came across was that I wanted my custom popup window to be positioned based on the location of the Windows Taskbar. There did not appear to be a WPF API to help there, so I resorted to the Win32 API and the SHAppBarMessage call:

[DllImport("shell32", CallingConvention = CallingConvention.StdCall)]
private static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

The APPBARDATA class is a simple struct that provides, amongst a few other things, the location of the Taskbar on the screen (left, top, right or bottom). By way of an example I’ve written a fun little application that I call the Taskbar Compass that points to the current position of the Taskbar.

The idea is that the red arrow points to where the Taskbar currently is. The application also listens for changes in user preferences and updates the compass if the Taskbar is moved. You can drag the window around as you would expect and a right mouse close will close it down. Take a look at a little movie I did to show the app in action:

<br> <a href="http://video.msn.com/video.aspx?vid=9be37e4c-6644-4961-a5f9-771e76cefe35" target="_new" title="Taskbar Compass">Video: Taskbar Compass</a>

You can download the sample application from here: TaskbarCompass.zip

As usual if you have a comments, questions, flames, enhancements I would love to hear from you; in the meantime think deeply and enjoy.

Synchronisation shock… you do not need Lock

|

When you write code that must work in a concurrent environment you may have to synchronise access a resource. It is very common to use a semaphore for this need; .NET is no different, and provides the Monitor class specifically for this purpose. You use the Monitor class like so:

private static object SyncObject = new object();
...
Monitor.Enter(SyncObject);
try
{
// thread sensitive code
}
finally
{
Monitor.Exit(SyncObject);
}

This code enters in to a critical section of code by using the Monitor.Enter() method, passing in a static sync object on which all threads can block; creating a mechanism to synchronise access to a thread sensitive resource. Then, after the code has completed its work with the resource, in the finally block, it exits the critical section with a call to Monitor.Exit() handing in the same sync lock object.

This was considered a common scenario by the C# designer, so common in fact a special keyword for exists to facilitate this pattern of Monitor usage; the keyword is called lock, and the following code that uses the lock keyword is semantically the same as the code shown above:

private static object SyncObject = new object();
...
lock(SyncObject)
{
// thread sensitive code
}

It is worth mentioning that the lock keyword does not actually do anything special; it simply emits the same code shown in the first code snippet in this post, by wrapping the use of the Monitor class in a try/finally guaranteeing that you exit the Monitor on exception.

While I would find it difficult to argue that this code is not simpler and cleaner than direct Monitor usage, I do assert that this is actually very rare scenario, and almost certainly not common enough to warrant a keyword all of its own! This may sound a little controversial but let me explain.

Consider for a moment that the vast majority of code that needs to be synchronised needs to also be atomic; therefore, if an exception is thrown during the execution of the code within the critical section you would not want your application to hobble on using potentially corrupt or broken data by blindly exiting the critical section. This would almost certainly put your application is an unstable state, creating intermittent and really tough to find and debug errors.

Now consider the scenario where you do not leave the critical section on error and simply report the exception and let the application hang the thread. Now you are in a situation that’s much easier to debug, as you’ll most likely be very near the call site where the error occurred, and your application is then not allowed to continue in an inconsistent state, which is a very good thing in my book.

Here’s a little sample code, showing what I think to be a more common scenario than that promoted by the use of the lock keyword:

private static object SyncObject = new object();
...
Monitor.Enter(SyncObject);
// thread sensitive code
Monitor.Exit(SyncObject);

Note this time there is no try/finally, so the code will stop on any unhandled exception (good thing). Obviously you can still wrap code of this nature in a try/catch, but then the normal rules of engagement come into play with regards to exception handling; it may even be appropriate to exit the critical section in the exception handler, and in that exception case you should probably use the lock keyword. However, I think that situation is rare; about as rare as actually handling a known exception, which of course you should only do when you can actually do something about it.

As usual if you have a comments, questions, flames, enhancements I would love to hear from you; but in the meantime happy multithreading, the future is concurrent and massively multithreaded, so think deeply and enjoy.

Newer Posts Older Posts Home