Question of the day: Threading

Here’s a little question about Threading – this would be a great interview question, in my opinion!

Given the code below:

public class Producer
{
    [ThreadStatic]
    readonly static private Producer _instance = new Producer();

    static private int _instanceCount;
    readonly private int _instanceId;

    private Producer()
    {
        _instanceId = ++_instanceCount;
    }

    static public Producer Instance
    {
        get { return _instance; }
    }

    public string Name
    {
        get
        {
            return String.Format("Instance {0} of {1}",
                _instanceId, _instanceCount);
        }
    }
}

public class Consumer
{
    public Consumer()
    {
        Thread t1 = new Thread(IdentifyProducer);
        t1.Start();

        Thread t2 = new Thread(IdentifyProducer);
        t2.Start();

        t1.Join();
        t2.Join();
    }

    public void IdentifyProducer()
    {
        Console.WriteLine(Producer.Instance.Name);
    }
}

What will happen when you create a new instance of the Consumer class?

Posted in Daily Question, Threading at June 30th, 2010. No Comments.

Star Sizing and Grid Size Sharing in WPF

They don’t work together. Full stop. Thank you Microsoft. The only way around this is to manually bind your columns/rows of one grid to another instead of using star sizing. Thanks to this article we can use this:

<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=OtherGrid}, Path=ColumnDefinitions[0].Width}" />
</Grid.ColumnDefinitions>
Posted in .Net at June 22nd, 2010. No Comments.

DateTime Localization in ASP .NET

You’ve got an ASP .NET app and you need to display a date. Normally that just involves the old DateTime.ToShortDateString() or DateTime.ToString(“d”) and you continue coding on your merry little way. But what happens when your users are from different countries and expect different date formats.  Between Australia, USA and Japan there are 3 different date formats.

Then answer? The HttpRequest’s UserLanguages. This string array basically maps to the following languages that you can setup in your browser:

Now for the code:


CultureInfo culture = Request.UserLanguages != null
? CultureInfo.CreateSpecificCulture(Request.UserLanguages[0])
: CultureInfo.CurrentCulture;
myLabel.Text = DateTimeOffset.Now.ToLocalTime().ToString("d", culture);
Don’t forget to check if the UserLanguages is not null since you can remove all the values from the list if you like.
Also, if you are looking at ways to do this client side, ScottGu’s Blog has a nice post on a new jquery plugin for this.

* Update *
Just realised that you don’t need to any of this if you use the following in your web.config:

<globalization uiCulture="auto" culture="auto" />
Posted in .Net, Asp.Net, C# at June 18th, 2010. No Comments.

Parsing comma separated values with regular expressions

We’ve all had to write code to parse comma separated values before; it sounds simple, but it can actually be quite tricky! Sure, if our lists were always nicely defined like this:

  • “one”,”two”,”three”,”four”
  • five,six,seven,eight

Then we could simply use String.Split. But life is never that kind! When your input strings may be a bit more loosely defined, like this:

  • one,”two,three”,four,,six,”seven”
  • ,two,”three,four,five”,,

It gets a little tougher.

So can you do it using a single regular expression? Yes, you most certainly can! It’s simply a matter of breaking down the possibilities, then catering for the best case scenario (quoted values), down to the worse case scenario (zero-length values), and finally, catering for the delimiters (either a comma, or the end of the string). Lets look at them one step at a time.

Firstly, quoted values. This is by far the easiest of all the conditions – find any length of text between two quotes. We’ll use a non-greedy expression (the question mark after the star) to ensure we don’t over-extend the length of text that we match:

private const string
    Template_QuotedValues = @"""(?<content>.*?)""";

The next easiest type of match to capture are non-quoted, non-zero length values. To do this, we’ll simply look for one or more characters which are not a comma. Again, we’re using a non-greedy match:

private const string
    Template_UnquotedValues = @"(?<content>[^,]+?)";

Notice also that that for both templates, we’re creating a named group called “content” – this allows us to easily extract the contents the match, no matter what conditions were matched under.

The last type of match we need to cater for is non-quoted, zero-length matches. This is the trickiest of the three situations, since there’s “nothing” to actually match on! So instead, we look zero repetitions of any character, immediately after a delimiter. Since the first value in the list may be empty, the possible values for our delimiter are either the start of string (specified by the hat – ^), or a comma:

private const string
    Template_EmptyValues = @"(?<=(?:,|^))(?<content>.{0})",

The final piece of the puzzle is the delimiters. Since we’re matching from left-to-right, we can assume that every match will be followed either by a comma, or the end of the string. We’ll use a non-capturing group since we don’t want the delimiter to be explicitly captured in a group.

private const string
    Template_Delimiter = @"(?=(?:,|$))";

Now, to put it all together. We have our three types of matches that we’re expecting, and our delimiter, so all we need to do is create a single RegEx for it all. Here goes:

private const string
    // Any length value within quotes...
    Template_QuotedValues = @"""(?<content>.*?)""",

    // ... or values with at least 1 character, not in quotes...
    Template_UnquotedValues = @"(?<content>[^,]+?)",

    // ...or zero-length matches, not in quotes...
    Template_EmptyValues = @"(?<=(?:,|^))(?<content>.{0})",

    // ... followed either a comma, or end of string
    Template_Delimiter = @"(?=(?:,|$))";

// Now join as one Template - notice the OR condition (pipe)
// between the three match types
readonly static private string
    Template = String.Format("({0}|{1}|{2}){3}",
        Template_QuotedValues,
        Template_UnquotedValues,
        Template_EmptyValues,
        Template_Delimiter);

// Finally, our RegEx!
readonly static private Regex CsvSplitterRegex
    = new Regex(Template, RegexOptions.Compiled);

Was that so bad? ;-) Iterating through the list of values in our comma separated list is now a piece of cake.

// Assume CSV is in "record" field
foreach (Match match in CsvSplitterRegex.Matches(record))
{
    Console.WriteLine("Match value: {0}",
        match.Groups["content"].Value);
}

Simple, eh?

Posted in C#, RegEx at May 15th, 2010. 2 Comments.

Handling of Nulls in Entity Framework

I think most of you can agree that we are advocates of Entity Framework here. But sometimes things can get a little hairy (as with all ORM solutions). So I just thought I’d post a quick solution to a problem that had me tearing my hair out at work to solve the other day.

Given the following two queries using Entity Framework one would assume the generated sql would the same?

string country = null;
var query = context.Orders.Where(o => o.Customer.Address.Country == country);
var query2 = context.Orders.Where(o => o.Customer.Address.Country == null);
Wrong. Thanks to this bug and this Microsoft article, I found out that not only will Entity Framwork will not honour what I have specified for ANSI NULLs, it will result in two inconsistent sql queries as the first query will do a “@country = null” comparison while the second query will do a “Country IS NULL” comparison.
Now, while I get that just because two objects are null it doesn’t mean they are equal, the workaround here can result in some ugly looking linq queries! Thank you ever so much Microsoft :)
Posted in .Net, C#, Sql Server at April 24th, 2010. 2 Comments.

Path resolution in ASP.NET

One thing I’ve always thought that ASP.NET doesn’t do a great job of is handling resource paths. For example, lets say on your development box, you have a website hosted under the virtual directory “MyProject”, such that you browse to http://localhost/MyProject/ to go to the home page. Lets also say that when you deploy the website to an external domain, it falls into the domain root, so instead you go to http://myproject.com/ to see your home page.

Sound familiar? The real problem then comes when you try and define a resource (e.g. a javascript file) using a relative path:

<script
    type="text/javascript"
    src="/Scripts/jquery.js">

This will work fine and dandy when you deploy the website, however on your local machine it will be looking for jquery at the path http://localhost/Scripts/jquery.js” – which more than likely isn’t going to work.

To get around this problem, I wrote a quick helper method called “Locate”, which I find myself reusing time and time again between websites. More often than not, I put it into a static class called “SiteManager” which basically just contains a bunch of helper functions relevant to the current website. Here’s the method:

/// <summary>
/// Resolves the path to a URL
/// </summary>
/// <param name="url">The path to be resolved, relative to the
/// application root</param>
/// <param name="formatArgs">String formatting arguments</param>
/// <returns>The URL</returns>
static public string Locate(string url, params object[] formatArgs)
{
    if (String.IsNullOrEmpty(url))
        url = "/";

    if (formatArgs != null && formatArgs.Length > 0)
        url = String.Format(url, formatArgs);

    HttpContext context = HttpContext.Current;
    return String.Concat(
        context.Request.ApplicationPath,
        !url.StartsWith("/") ? "/" : String.Empty,
        url);
}

To use the method, you simply change your script declaration (or whatever resource you’re trying to find) as follows:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/jquery.js") %>">
</script>

You’ll also notice that it supports string formatting – so even though it would be pointless in this particular example, you could, if you preferred, do something like this:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/{0}.js", "jquery") %>">
</script>

In both instances, this will resolve the URL in your output document using the current application path –

  • http://localhost/MyProject/Scripts/jquery.js on your local machine; and
  • http://myproject.com/Scripts/jquery.js on the web server.

Enjoy!

Posted in Asp.Net, C# at January 14th, 2010. 5 Comments.

Creating your own ContentTemplates in WPF

This isn’t something that I do often, but rolling your own look-and-feel by starting a ContentTemplate from scratch can be a right pain in the botty. Today I found this excellent sample project from Microsoft, which contains custom ContentTemplates for most UI controls in the framework. It provides an excellent starting point for creating your own customized controls.

Check it out!

Posted in .Net, WPF at December 23rd, 2009. 1 Comment.

Quick WPF Performance Statistics

Just thought I’d put out some quick WPF performance statistics thanks to Microsoft. You can download the entire slideshow here.
  • DependencyProperty is x3 faster than INotifyPropertyChanged
  • ObservableCollection accesses single items 90 times faster than List
  • ObjectDataProvider is x20 smaller than XmlDataProvider

Microsoft also have some other good tips over here too.
I’d like to see some real world statistics on the differences between using static vs dynamic resources too. Anybody know of any?

Posted in .Net, C# at December 23rd, 2009. 1 Comment.

Containing floats in HTML

Have you ever created a block-level element (e.g. a div), whose only contents are floating elements – only to find that your block-level element doesn’t stretch down to contain it’s children? Well, I have, and it’s a problem that always annoys me because I can never bring to mind the easiest way of fixing it.

The simplest solution is to use “overflow:hidden” in the style of your parent element, however this doesn’t work for all browsers scenarios. So, for a much more comprehensive description of the problem, as well as a number of approaches you can use to solve it, check out this post.

Posted in Asp.Net at November 27th, 2009. No Comments.

AutoMapper

Ever had those mundane tasks of mapping your entities to Data Transfer Objects for use in your service layer? While browsing the web the other day I found this great tool called AutoMapper which does a superb job in filling this void.

Writing mapping code is painful, creates more work and means you have more tests to write. This is where AutoMapper fits in.

Given the following entities:

public class Bank {
public string Name{ get; set; }
}

public class Customer {
public string Name { get; set; }
public Bank BankDetails{ get; set; }
}

public class CustomerDTO {
public string Name { get; set; }
public string BankName{ get; set; }
}

Now all we need to do is use the mapper in code like so:

AutoMapper.CreateMap<Customer, CustomerDTO>(); //setup the mappings
Customer newCustomer = new Customer() {Name = "test" };
CustomerDTO transformedCustomer = AutoMapper.Map<Customer, CustomerDTO>(newCustomer);

Brilliant! We now have a working CustomerDTO object and it even mapped our BankName for us without even setting up any custom mapping. Here is what AutoMapper can do for you:

  • Matching property names
  • Methods starting with the word “Get” automatically get mapped. e.g. GetAccountBalance() maps to AccountBalance
  • Nested property names (Bank.Name maps to BankName, pretty sure this only works with PascalCase)

AutoMapper can also map collections for you too. One of the things to remember here is you don’t need to create a mapping for collections, just the element types.

For the testers amongst us I hear you say that you now can’t test your mappings like you could before with custom mapping code. Well there is an answer to this.

Mapper.AssertConfigurationIsValid();

This method will assert that all properties from the source will be mapped to something on the destination object. Mapping objects is now no longer painful!

Posted in .Net at November 15th, 2009. 4 Comments.