Code Trivia #7

Lets go for another code trivia, it’s business as usual, you just need to find what’s wrong with the following code:

static void Main(string[] args)
{
    using (var file = new FileStream("test", FileMode.Create) { WriteTimeout = 1 })
    {
        file.WriteByte(0);
    }
}

TIP: There’s something very wrong with this specific code and there’s also another subtle problem that arises due to how the code is structured.


As explained in the comments, the using statement expands to the following code leading to the FileStream object never getting disposed because the finally is never executed.

FileStream file = new FileStream("test", FileMode.Create) { WriteTimeout = 1 };
try
{
    file.WriteByte(0);
}
finally
{
    if (file != null)
        ((IDisposable)file).Dispose();
}

With this in mind, one could be tempted to use a custom try/finally block for handling this situation. Something like this:

FileStream file = null;
try
{
    file = new FileStream("test", FileMode.Create)
    {
        WriteTimeout = 1
    };

    file.WriteByte(0);
}
finally
{
    if (file != null)
        file.Dispose();
}

However this suffers from the same problem but due to a different cause. Even though the constructor for the object is called inside the try clause the object initializer syntax prevents it from being assigned to the file variable before all properties have been initialized, leading to the file stream still not being disposed.

The expansion caused by the object initializer syntax is shown in the next sample of code:

FileStream file = null;
try
{
    FileStream compilerGenerated = new FileStream("test", FileMode.Create);

    compilerGenerated.WriteTimeout = 1;

    file = compilerGenerated;

    file.WriteByte(0);
}
finally
{
    if (file != null)
        file.Dispose();
}

Basically, you need to be careful with using blocks where the resource initialization expression may throw an exception and you also need to pay careful attention on the subtleties of using object initializer syntax.

Razor – Hiding a Section in a Layout

Layouts in Razor allow you to define placeholders named sections where content pages may insert custom content much like the ContentPlaceHolder available in ASPX master pages.

When you define a section in a Razor layout it’s possible to specify if the section must be defined in every content page using the layout or if its definition is optional allowing a page not to provide any content for that section. For the latter case, it’s also possible using the IsSectionDefined method to render default content when a page does not define the section.

However if you ever require to hide a given section from all pages based on some runtime condition you might be tempted to conditionally define it in the layout much like in the following code snippet.

if(condition) {
	@RenderSection("ConditionalSection", false)
}

With this code you’ll hit an error as soon as any content page provides content for the section which makes sense since if a page inherits a layout then it should only define sections that are also defined in it.

To workaround this scenario you have a couple of options. Make the given section optional with and move the condition that enables or disables it to every content page. This leads to code duplication and future pages may forget to only define the section based on that same condition.

The other option is to conditionally define the section in the layout page using the following hack:

@{
    if(condition) {
        @RenderSection("ConditionalSection", false)
    } 
    else {
        RenderSection("ConditionalSection", false).WriteTo(TextWriter.Null);
    }
}

Hack inspired by a recent stackoverflow question.

Unit Testing with NUnit and Moles Redux

Almost two years ago, when Moles was still being packaged alongside Pex, I wrote a post on how to run NUnit tests supporting moled types.

A lot has changed since then and Moles is now being distributed independently of Pex, but maintaining support for integration with NUnit and other testing frameworks.

For NUnit the support is provided by an addin class library (Microsoft.Moles.NUnit.dll) that you need to reference in your test project so that you can decorate yours tests with the MoledAttribute. The addin DLL must also be placed in the addins folder inside the NUnit installation directory.

There is however a downside, since Moles and NUnit follow a different release cycle and the addin DLL must be built against a specific NUnit version, you may find that the release included with the latest version of Moles does not work with your version of NUnit.

Fortunately the code for building the NUnit addin is supplied in the archive (moles.samples.zip) that you can found in the Documentation folder inside the Moles installation directory. By rebuilding the addin against your specific version of NUnit you are able to support any version.

Also to note that in Moles 0.94.51023.0 the addin code did not support the use of TestCaseAttribute in your moled tests. However, if you need this support, you need to make just a couple of changes.

Change the ITestDecorator.Decorate method in the MolesAddin class:

Test ITestDecorator.Decorate(Test test, MemberInfo member)
{
    SafeDebug.AssumeNotNull(test, "test");
    SafeDebug.AssumeNotNull(member, "member");

    bool isTestFixture = true;
    isTestFixture &= test.IsSuite;
    isTestFixture &= test.FixtureType != null;

    bool hasMoledAttribute = true;
    hasMoledAttribute &= !SafeArray.IsNullOrEmpty(
        member.GetCustomAttributes(typeof(MoledAttribute), false));

    if (!isTestFixture && hasMoledAttribute)
    {
        return new MoledTest(test);
    }

    return test;
}

Change the Tests property in the MoledTest class:

public override System.Collections.IList Tests
{
    get
    {
        if (this.test.Tests == null)
        {
            return null;
        }

        var moled = new List<Test>(this.test.Tests.Count);

        foreach (var test in this.test.Tests)
        {
            moled.Add(new MoledTest((Test)test));
        }

        return moled;
    }
}

Disclaimer: I only tested this implementation against NUnit 2.5.10.11092 version.

Finally you just need to run the NUnit console runner through the Moles runner. A quick example follows:

moles.runner.exe [Tests.dll] /r:nunit-console.exe /x86 /args:[NUnitArgument1] /args:[NUnitArgument2]

Assembly Resources Expression Builder

In ASP.NET you can tackle the internationalization requirement by taking advantage of native support to local and global resources used with the ResourceExpressionBuilder.

But with this approach you cannot access public resources defined in external assemblies referenced by your Web application.

However, since you can extend the .NET resource provider mechanism and create new expression builders you can workaround this limitation and use external resources in your ASPX pages much like you use local or global resources.

Finally, if you are thinking, okay this is all very nice but where’s the code I can use? Well, it was too much to publish directly here so download it from Helpers.Web@Codeplex, where you also find a sample on how to configure and use it.

VSTO Troubleshooting Quick Tips

If you ever find yourself troubleshooting a VSTO addin that does not load then these steps will interest you.

  1. Do not skip the basics and check the registry at HKLM\Software\Microsoft\Office\<Application>\AddIns\<AddInName> or HKCU\Software\Microsoft\Office\<Product>\AddIns\<Application> because if the LoadBehavior key is not set to 3 the office application will not even try to load it on startup;
  2. Enable error alerts popups by configuring an environment variable
    SET VSTO_SUPPRESSDISPLAYALERTS=0
  3. Enable logging errors to file by configuring an environment variable
    SET VSTO_LOGALERTS=1
  4. Pray for an error alert popup or for an error in the log file so that you can fix its cause.

 

Visual Studio Macro – Identifier to String Literal

When implementing public methods with parameters it’s important to write boiler-plate code to do argument validation and throw exceptions when needed, ArgumentException and ArgumentNullException being the most recurrent.

Another thing that is important is to correctly specify the parameter causing the exception through the proper exception constructor.

In order to take advantage of IntelliSense completion in these scenarios I use a Visual Studio macro binded to a keyboard shortcut that converts the identifier at the cursor position to a string literal.

And here’s the macro:

Sub ConvertIdentifierToStringLiteral()
    Dim targetWord As String
    Dim document As EnvDTE.TextDocument

    document = CType(DTE.ActiveDocument.Object, EnvDTE.TextDocument)

    If document.Selection.Text.Length > 0 Then
        targetWord = document.Selection.Text
        document.Selection.ReplacePattern(targetWord, """" + targetWord + """")
    Else
        Dim cursorPoint As EnvDTE.TextPoint

        cursorPoint = document.Selection.ActivePoint()

        Dim editPointLeft As EnvDTE.EditPoint
        Dim editPointRight As EnvDTE.EditPoint

        editPointLeft = cursorPoint.CreateEditPoint()
        editPointLeft.WordLeft(1)

        editPointRight = editPointLeft.CreateEditPoint()
        editPointRight.WordRight(1)

        targetWord = editPointLeft.GetText(editPointRight)
        editPointLeft.ReplaceText(editPointRight, """" + targetWord + """", 0)
    End If
End Sub

Extended FindWindow

The Win32 API provides the FindWindow function that supports finding top-level windows by their class name and/or title. However, the title search does not work if you are trying to match partial text at the middle or the end of the full window title.

You can however implement support for these extended search features by using another set of Win32 API like EnumWindows and GetWindowText. A possible implementation follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

public class WindowInfo
{
    private IntPtr handle;

    private string className;

    internal WindowInfo(IntPtr handle, string title)
    {
        if (handle == IntPtr.Zero)
            throw new ArgumentException("Invalid handle.", "handle");

        this.Handle = handle;
        this.Title = title ?? string.Empty;
    }

    public string Title { get; private set; }

    public string ClassName
    {
        get
        {
            if (className == null)
            {
                className = GetWindowClassNameByHandle(this.Handle);
            }

            return className;
        }
    }

    public IntPtr Handle
    {
        get
        {
            if (!NativeMethods.IsWindow(this.handle))
                throw new InvalidOperationException("The handle is no longer valid.");

            return this.handle;
        }
        private set { this.handle = value; }
    }

    public static WindowInfo[] EnumerateWindows()
    {
        var windows = new List<WindowInfo>();

        NativeMethods.EnumWindowsProcessor processor = (hwnd, lParam) =>
        {
            windows.Add(new WindowInfo(hwnd, GetWindowTextByHandle(hwnd)));

            return true;
        };

        bool succeeded = NativeMethods.EnumWindows(processor, IntPtr.Zero);

        if (!succeeded)
            return new WindowInfo[] { };

        return windows.ToArray();
    }

    public static WindowInfo FindWindow(Predicate<WindowInfo> predicate)
    {
        WindowInfo target = null;

        NativeMethods.EnumWindowsProcessor processor = (hwnd, lParam) =>
        {
            var current = new WindowInfo(hwnd, GetWindowTextByHandle(hwnd));

            if (predicate(current))
            {
                target = current;

                return false;
            }

            return true;
        };

        NativeMethods.EnumWindows(processor, IntPtr.Zero);

        return target;
    }

    private static string GetWindowTextByHandle(IntPtr handle)
    {
        if (handle == IntPtr.Zero)
            throw new ArgumentException("Invalid handle.", "handle");

        int length = NativeMethods.GetWindowTextLength(handle);

        if (length == 0)
            return string.Empty;

        var buffer = new StringBuilder(length + 1);

        NativeMethods.GetWindowText(handle, buffer, buffer.Capacity);

        return buffer.ToString();
    }

    private static string GetWindowClassNameByHandle(IntPtr handle)
    {
        if (handle == IntPtr.Zero)
            throw new ArgumentException("Invalid handle.", "handle");

        const int WindowClassNameMaxLength = 256;

        var buffer = new StringBuilder(WindowClassNameMaxLength);

        NativeMethods.GetClassName(handle, buffer, buffer.Capacity);

        return buffer.ToString();
    }
}

internal class NativeMethods
{
    public delegate bool EnumWindowsProcessor(IntPtr hwnd, IntPtr lParam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumWindows(
        EnumWindowsProcessor lpEnumFunc,
        IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetWindowText(
        IntPtr hWnd,
        StringBuilder lpString,
        int nMaxCount);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetClassName(
        IntPtr hWnd,
        StringBuilder lpClassName,
        int nMaxCount);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsWindow(IntPtr hWnd);
}

The access to the windows handle is preceded by a sanity check to assert if it’s still valid, but if you are dealing with windows out of your control then the window can be destroyed right after the check so it’s not guaranteed that you’ll get a valid handle.

Finally, to wrap this up a usage, example:

static void Main(string[] args)
{
    var w = WindowInfo.FindWindow(wi => wi.Title.Contains("Test.docx"));

    if (w != null)
    {
        Console.Write(w.Title);
    }
}

Inside BackgroundWorker

The BackgroundWorker is a reusable component that can be used in different contexts, but sometimes with unexpected results.

If you are like me, you have mostly used background workers while doing Windows Forms development due to the flexibility they offer for running a background task. They support cancellation and give events that signal progress updates and task completion.

When used in Windows Forms, these events (ProgressChanged and RunWorkerCompleted) get executed back on the UI thread where you can freely access your form controls.

However, the logic of the progress changed and worker completed events being invoked in the thread that started the background worker is not something you get directly from the BackgroundWorker, but instead from the fact that you are running in the context of Windows Forms.

Take the following example that illustrates the use of a worker in three different scenarios:

– Console Application or Windows Service;
– Windows Forms;
– WPF.

using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Threading;

class Program
{
    static AutoResetEvent Synch = new AutoResetEvent(false);

    static void Main()
    {
        var bw1 = new BackgroundWorker();
        var bw2 = new BackgroundWorker();
        var bw3 = new BackgroundWorker();

        Console.WriteLine("DEFAULT");
        var unspecializedThread = new Thread(() =>
        {
            OutputCaller(1);

            SynchronizationContext.SetSynchronizationContext(
                new SynchronizationContext());

            bw1.DoWork += (sender, e) => OutputWork(1);
            bw1.RunWorkerCompleted += (sender, e) => OutputCompleted(1);
            // Uses default SynchronizationContext
            bw1.RunWorkerAsync();
        });
        unspecializedThread.IsBackground = true;
        unspecializedThread.Start();

        Synch.WaitOne();

        Console.WriteLine();
        Console.WriteLine("WINDOWS FORMS");
        var windowsFormsThread = new Thread(() =>
        {
            OutputCaller(2);

            SynchronizationContext.SetSynchronizationContext(
                new WindowsFormsSynchronizationContext());

            bw2.DoWork += (sender, e) => OutputWork(2);
            bw2.RunWorkerCompleted += (sender, e) => OutputCompleted(2);
            // Uses WindowsFormsSynchronizationContext
            bw2.RunWorkerAsync();

            Application.Run();
        });
        windowsFormsThread.IsBackground = true;
        windowsFormsThread.SetApartmentState(ApartmentState.STA);
        windowsFormsThread.Start();

        Synch.WaitOne();

        Console.WriteLine();
        Console.WriteLine("WPF");
        var wpfThread = new Thread(() =>
        {
            OutputCaller(3);

            SynchronizationContext.SetSynchronizationContext(
                new DispatcherSynchronizationContext());

            bw3.DoWork += (sender, e) => OutputWork(3);
            bw3.RunWorkerCompleted += (sender, e) => OutputCompleted(3);
            // Uses DispatcherSynchronizationContext
            bw3.RunWorkerAsync();

            Dispatcher.Run();
        });
        wpfThread.IsBackground = true;
        wpfThread.SetApartmentState(ApartmentState.STA);
        wpfThread.Start();

        Synch.WaitOne();
    }

    static void OutputCaller(int workerId)
    {
        Console.WriteLine(
            "bw{0}.{1} | Thread: {2} | IsThreadPool: {3}",
            workerId,
            "RunWorkerAsync".PadRight(18),
            Thread.CurrentThread.ManagedThreadId,
            Thread.CurrentThread.IsThreadPoolThread);
    }

    static void OutputWork(int workerId)
    {
        Console.WriteLine(
            "bw{0}.{1} | Thread: {2} | IsThreadPool: {3}",
            workerId,
            "DoWork".PadRight(18),
            Thread.CurrentThread.ManagedThreadId,
            Thread.CurrentThread.IsThreadPoolThread);
    }

    static void OutputCompleted(int workerId)
    {
        Console.WriteLine(
            "bw{0}.{1} | Thread: {2} | IsThreadPool: {3}",
            workerId,
            "RunWorkerCompleted".PadRight(18),
            Thread.CurrentThread.ManagedThreadId,
            Thread.CurrentThread.IsThreadPoolThread);

        Synch.Set();
    }
}

Output:

//DEFAULT
//bw1.RunWorkerAsync     | Thread: 3 | IsThreadPool: False
//bw1.DoWork             | Thread: 4 | IsThreadPool: True
//bw1.RunWorkerCompleted | Thread: 5 | IsThreadPool: True

//WINDOWS FORMS
//bw2.RunWorkerAsync     | Thread: 6 | IsThreadPool: False
//bw2.DoWork             | Thread: 5 | IsThreadPool: True
//bw2.RunWorkerCompleted | Thread: 6 | IsThreadPool: False

//WPF
//bw3.RunWorkerAsync     | Thread: 7 | IsThreadPool: False
//bw3.DoWork             | Thread: 5 | IsThreadPool: True
//bw3.RunWorkerCompleted | Thread: 7 | IsThreadPool: False

As you can see the output between the first and remaining scenarios is somewhat different. While in Windows Forms and WPF the worker completed event runs on the thread that called RunWorkerAsync, in the first scenario the same event runs on any thread available in the thread pool.

Another scenario where you can get the first behavior, even when on Windows Forms or WPF, is if you chain the creation of background workers, that is, you create a second worker in the DoWork event handler of an already running worker. Since the DoWork executes in a thread from the pool the second worker will use the default synchronization context and the completed event will not run in the UI thread.

1512 Hours Without Internet

Tonight’s the night, that I’m finally back online after two months of being disconnected from the online world, at least while not at work, but that doesn’t count.

This was completely unplanned and caused by infra-structures problems from my new ISP, but they finally sorted it out and I’m online again.

VS 2010 SP1 BETA – App.config XML Transformation Fix

The current version for App.config XML tranformations as described in a previous post does not support the SP1 BETA version of Visual Studio. I did some quick tests and decided to provide a different version with a compatibility fix for those already experimenting with the beta release of the service pack.

This is a quick workaround to the build errors I found when using the transformations in SP1 beta and is pretty much untested since I’ll wait for the final release of the service pack to take a closer look to any possible problems.

But for now, those that already installed SP1 beta can use the following transformations:

VS 2010 SP1 BETA – App.config XML Transformation

And those with the RTM release of Visual Studio can continue to use the original version of the transformations available from:

VS 2010 RTM – App.config XML Transformation

Follow

Get every new post delivered to your Inbox.