Singleton WCF service gotcha: allowing more than 10 connections

By default, an instance of a WCF service can only have 10 connections at a time. If your service is a singleton then there is obviously only one instance, which means that only 10 clients can connect to your service at a time. All subsequent connection attempts will result in timeouts if one of the 10 spots is not freed up. You can easily change this from the default by adding a serviceThrottling entry to your behavior definition in the app.config/web.config file. Here’s an example that cranks the max up to 50:

<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="50" maxConcurrentInstances="50" />

Updating and restarting a singleton WCF service hosted in IIS

I recently moved a singleton WCF service to IIS that used to be hosted within a Windows service. When it was hosted in a Windows service restarting it was easy, you just go to the service manager in Windows and click restart, but to my knowledge there is no direct equivalent for a WCF service running inside IIS. Since a singleton service continues to run indefinitely once it starts I was afraid that even after publishing an update or changing the web.config the old code would continue to run until I forced a restart somehow. I didn’t want to have to restart IIS every time there is a change to the config file, so I made a test project and ran some experiments. It turns out that when any change is made to the service (ie: any of the binaries, the svc file, or the web.config are replaced) the service immediately restarts. This means that all of your existing connections will be terminated and the service class will be recreated. Unlike a Windows service you don’t have to manually force a restart when you publish an update. The bad news is that I still don’t know of a way to simply restart the service without making any changes. Aside from restarting IIS (which is obviously a terrible solution) the only way I know is to make some random negligible change to the config file (like changing a comment or maybe even just whitespace). I guess that in theory singleton services are not meant to be restarted, but you’re bound to want to do it at some point.

CruiseControl.NET: Versioning ccnet.config and integrating it into CI

Cruise Control is meant to help manage your builds based on the code in source control, and since ccnet config files are basically code, it only makes sense that they should be a part of this process. Basically, there are two problems I wanted to solve:

  • If I change ccnet.config and introduce an error, I want to be able to roll back to a previous version in SVN.
  • When multiple developers are working on ccnet.config, they should not be fighting over the same file on the CI server. Instead, each developer should be editing a file in their working copy and then merging changes into the repository.

Both of these issues are actually very easy to solve. Using SVN, you can create a repository with only one file: ccnet.config. Then add this project to both the ccnet.config in SVN and the one actually used by Cruise Control (probably in C:\Program Files\CruiseControl.NET or something like that):

  <project name="ccnet config">
    <sourcecontrol type="svn">
      <executable>C:\path\to\svn\on\CI\server\svn.exe</executable>
      <workingDirectory>C:\CI</workingDirectory>
      <trunkUrl>http://localhost/svn/myrepo/trunk</trunkUrl>
      <autoGetSource>true</autoGetSource>
      <username>SVN_USERNAME</username>
      <password>SVN_PASSWORD</password>
    </sourcecontrol>
    <tasks>
      <exec>
        <executable>C:\Windows\System32\xcopy.exe</executable>
        <buildArgs>/Y C:\CI\ccnet-config\ccnet.config "C:\Program Files\CruiseControl.NET\server"</buildArgs>
      </exec>
    </tasks>
  </project>

All this does is check out the config file and then copy it to the location used by Cruise Control. Remember to edit all the paths above with the actual ones for your setup.

That’s all you need to do! The config file is now versioned and Cruise Control is automatically updating itself every time you commit.

LINQ to SQL Gotcha #5: Column Default Values

A common pattern in database design is to use make a column required, give it a default value and then never think about it when doing INSERTs. A perfect example would be a createdDate column on the Users with a default value of GetDate(). Here’s the full table definition:

  • userID (identity key)
  • userName
  • password
  • ts (timestamp)
  • createdDate (default value = GetDate())

In this case we can easily insert into the table without worrying about the createdDate, userID, or ts columns:

INSERT INTO Users (userName, password) VALUES ('asdf', 'qwer')

However, since this is the 21st century, we don’t want to do this in SQL, we want to do it with an ORM. Unfortunately, LINQ to SQL doesn’t do a very good job with this.

Using context = New TestDataContext
 
    ' Output SQL to the console for debugging
    context.Log = Console.Out
 
    ' Attach a new user and submit the changes
    Dim newUser As New User With {.userName = "NewUser", .password = "password"}
    context.Users.InsertOnSubmit(newUser)
    context.SubmitChanges()
 
End Using

The above code generates the following INSERT statement when SubmitChanges() is called (note: I replaced @p0, @p1, etc with their actual values to make the query more readable):

INSERT INTO [dbo].[Users]([userName], [password], [createdDate]) VALUES ('NewUser', 'password', NULL)

This query fails and we get a SqlTypeException because createdDate is NOT NULL and NULL cannot be converted to a valid date. Notice that the generated SQL does not attempt to explicitly set a value for userID or ts. It appears that LINQ to SQL knows how to deal with IDENTITY fields and TIMESTAMPs, but not how to deal with other required columns that happen to have a default value.

I would have expected LINQ to SQL to generate a query that does not explicitly set createdDate so that SQL Server could handle it, but no such luck. You can easily set the createdDate manually like this:

Dim newUser As New User With {.userName = "NewUser", .password = "password", .createdDate = Date.Now}

It really sucks to have to do this every time though, especially if you have many fields to fill in. A possible alternative is to put a partial class on either your DataContext or just on the User class and write some code that will automatically initialize fields like createdDate. If you want to make generic behaviour for this (eg: automatically set columns named “createdDate” to Date.Now when SubmitChanges is called) you can do something like this in the DataContext partial class:

Public Overrides Sub SubmitChanges(ByVal failureMode As ConflictMode)
 
    ' NOTE: this is just a sample to get you started
    For Each insert In GetChangeSet().Inserts
        Dim createdDateProp = insert.GetType.GetProperty("createdDate")
        If createdDateProp IsNot Nothing Then
            createdDateProp.SetValue(insert, Date.Now, Nothing)
        End If
    Next
 
    MyBase.SubmitChanges(failureMode)
 
End Sub

Saving changes to stored procedure results in LINQ to SQL

The great thing about fetching data via a LINQ to SQL query is that you get a nice formatted result and you can easily save back any changes you make with SubmitChanges(). Unfortunately, we all inevitably fall into scenarios where we have to make use of stored procedures for performance or other reasons. If you have a stored procedure whose result set contains columns from just a single table then you can easily map the stored procedure to that table, but in most cases the result set involves multiple tables making things a little more tricky. It’s easy to execute a stored procedure from LINQ to SQL (just drag the SP from the server explorer into the designer and then execute it like a function on the data context) but you lose some of the benefits of LINQ to SQL. First of all, you just get a flat result set instead of a hierarchical result set using the auto generated entity classes. Second, you can’t just make changes to the result and call SubmitChanges. Luckily, with a little extra work, the flat, detached result set can be converted into a hierarchical, attached result set where changes can easily be saved.

If you don’t want to bother reading the whole article and all of the code, here’s the short answer: use the Attach() method.

Below is an example that runs a stored procedure to return all users in the database joined with their articles. The results are converted into an attached list of users, each containing a collection of articles. Notice that not all of the columns need to be known, just the primary key and timestamp are required. For more info on the timestamp, check out this article.

Module Module1
 
    Sub Main()
 
        Using testContext As New TestDataContext
 
            ' Print SQL queries to the console for testing purposes
            testContext.Log = Console.Out
 
            ' Get attached entities
            Dim users = GetAttachedUsersWithGroups(testContext)
 
            ' Make some random changes to prove the concept
            users.First.userName = "foo"
            users.First.Articles.First.text = "bar"
 
            ' Submit the changes to see what SQL gets executed
            testContext.SubmitChanges()
 
        End Using
 
        Console.ReadKey()
 
    End Sub
 
    Public Function GetAttachedUsersWithGroups(ByVal context As TestDataContext) As IEnumerable(Of User)
 
        ' Get some data from a stored procedure
        Dim result = context.GetAllUsersWithArticles
 
        ' Convert flat result set to groups of articles by user
        Dim userGroups = From row In result _
                         Group row By row.userID, row.userTimestamp _
                         Into articles = Group _
                         Select userID, userTimestamp, articles
 
        Dim users As New List(Of User)
 
        ' Create LINQ to SQL entities
        For Each userGroup In userGroups
            Dim user As New User With {.userID = userGroup.userID, _
                                       .ts = userGroup.userTimestamp}
            For Each article In userGroup.articles
                user.Articles.Add(New Article With {.articleID = article.articleID, _
                                                    .title = article.title, _
                                                    .ts = article.articleTimestamp})
            Next
            users.Add(user)
        Next
 
        ' Attach the users to the data context.  This will also attach the articles
        ' because they have been added to each user's Articles collection.
        context.Users.AttachAll(users)
 
        Return users
 
    End Function
 
End Module

LINQ to SQL Gotcha #4: ChangeConflictException on Update of Manually Attached Data

LINQ to SQL has built in optimistic concurrency checking. When you create an unattached entity and then attach it (ie: with the Attach() function) the concurrency check will always fail by throwing a ChangeConflictException unless one of the two are true:

  • The table that the entity belongs to has a timestamp column and its value is exactly the same as it appears in the database.
  • There is no timestamp column but the “no count” feature on SQL Server is off.

Using a timestamp column seems like the more elegant solution, but it does require that you know the timestamp value. This usually means that if you’re attaching the result of a stored procedure so that you can save back the results, your stored procedure needs to return the timestamp in addition to the primary key.

LINQ to SQL Gotcha #3: Chaining Where Clauses

In LINQ to SQL you can chain multiple where clauses like this:

Module Module1
 
    Sub Main()
 
        Using context As New TestDataContext
            context.Log = Console.Out
            Dim articles = context.Articles.Where(Function(a) a.articleID > 10) _
                                           .Where(Function(a) a.articleID Mod 2 = 0) _
                                           .ToList()
        End Using
 
        Console.ReadKey()
 
    End Sub
 
End Module

This will generate SQL that looks roughly like this:

SELECT ... FROM Articles WHERE articleID > 10 AND articleID % 2 = 0

Since chained where clauses are equivalent to ANDing multiple expressions in a single WHERE, the above SQL is exactly what you would expect to see. Unfortunately, things get more complicated when one of the expressions cannot be converted to SQL, like in this case:

Module Module1
 
    Sub Main()
 
        Using context As New TestDataContext
            context.Log = Console.Out
            Dim articles = context.Articles.Where(AddressOf FilterArticle).ToList()
        End Using
 
        Console.ReadKey()
 
    End Sub
 
    Function FilterArticle(ByVal a As Article) As Boolean
        Return a.articleID Mod 2 = 0
    End Function
 
End Module

The above code generates SQL that looks like this:

SELECT ... FROM Articles

The query has no where clause, it just loads all the articles and then filters them on the client side. It’s usually optimal to do the filtering on the SQL side, but the behaviour is reasonable. I wouldn’t expect the ORM to be capable of magically converting the contents of the FilterArticle function into SQL (it sure would be nice though). This is still expected behaviour, but here’s an example where things get weird:

Module Module1
 
    Sub Main()
 
        Using context As New TestDataContext
            context.Log = Console.Out
            Dim articles = context.Articles.Where(AddressOf FilterArticle) _
                                           .Where(Function(a) a.articleID > 10) _
                                           .ToList()
        End Using
 
        Console.ReadKey()
 
    End Sub
 
    Function FilterArticle(ByVal a As Article) As Boolean
        Return a.articleID Mod 2 = 0
    End Function
 
End Module

This code generates the same SQL as last time:

SELECT ... FROM Articles

It is filtering both where clauses on the client side even though the second one could have been converted to SQL. If you flip the where clauses like this:

Module Module1
 
    Sub Main()
 
        Using context As New TestDataContext
            context.Log = Console.Out
            Dim articles = context.Articles.Where(Function(a) a.articleID > 10) _
                                           .Where(AddressOf FilterArticle) _
                                           .ToList()
        End Using
 
        Console.ReadKey()
 
    End Sub
 
    Function FilterArticle(ByVal a As Article) As Boolean
        Return a.articleID Mod 2 = 0
    End Function
 
End Module

then you will still get the expected SQL:

SELECT ... FROM Articles WHERE articleID > 10

The where clause that can be converted to SQL is filtered in the SELECT statement, but the clause that cannot be converted is filtered on the client side. I would have hoped that the order of the where clauses would not matter since they are just being ANDed, but that is not the case.

The lesson is that if you need to chain a where clause that cannot be converted to SQL, try to put it at the end of the chain. This can be a real issue if you are using a data access layer that automatically filters queries (eg: for security) with a function that cannot convert to SQL. If all of your LINQ to SQL queries have this built in filter then none of them will ever generate WHERE clauses in the SQL, it will just load the entire table every time.

WPF Responsiveness: Asynchronous Loading Animations During Rendering

Download the code here: WpfLoadingOverlay.zip

A common issue in MDI or TDI style user interfaces is that it can take a long time to render new forms when they are opened. Even a one or two second delay is enough to make an application seem very unresponsive. If there’s nothing you can do to improve the actual performance (ie: the total time to load the form) you can at least improve the perceived performance. This code sample creates a simple form with a tab control and a button. Every time you click the button it adds a new tab with 4000 text boxes. Depending on the speed of your computer the form will probably take around five seconds to load. As soon as you click the button, the new tab appears with a loading animation that continues until the contents have been rendered. This is not a trivial task because we want to render a loading animation at the same time that we are waiting for another long rendering operation to complete. Basically, we need two rendering threads. You can’t have multiple rendering threads in a single window, but you can put your loading animation in a new window with its own rendering thread and make it look like it’s not a separate window.

The loading overlay is a separate, chromeless window that does not appear on the taskbar and disappears as soon as loading is complete. The window is also semi-transparent and automatically positioned exactly over top of the form that is loading, so it looks like it is a part of the existing window.

Download the sample project and try it out.

LINQ to SQL Gotcha #2: GetChangeSet Weirdness

If you attach an entity with a required association that is nulled out, you will be unable to call GetChangeSet(). In my opinion, the expected behaviour is that the entity should show up in the change set as though it is valid, but an exception should be thrown when you attempt to call SubmitChanges() because a foreign key constraint has been violated. In fact, with code like this we will get exactly that result (an exception is thrown on SubmitChanges()):

Using testData As New TestDataContext
    Dim newArticle As New Article With {.title = "Foobar", _
                                        .text = "blah blah blah"}
    testData.Articles.InsertOnSubmit(newArticle)
    Dim changes = testData.GetChangeSet()
    testData.SubmitChanges()
End Using

There is a required association to the Users table that has not been set at all. Using the following snippet, with the User property explicitly set to Nothing an exception will be thrown on GetChangeSet() instead of SubmitChanges():

Using testData As New TestDataContext
    Dim newArticle As New Article With {.title = "Foobar", _
                                        .text = "blah blah blah", _
                                        .User = Nothing}
    testData.Articles.InsertOnSubmit(newArticle)
    Dim changes = testData.GetChangeSet()
    testData.SubmitChanges()
End Using

It gives this error on GetChangeSet():

An attempt was made to remove a relationship between a User and a Article. However, one of the relationship’s foreign keys (Article.userID) cannot be set to null.

It appears that the internal implementation of LINQ to SQL distinguishes between an unset relationship, and one that has specifically been set to Nothing. The awkward thing here is that it is not always easy to avoid this issue since you don’t even have to call InsertOnSubmit. Attaching an entity by setting an association to an already attached object gives the same result.

Using testData As New TestDataContext
    Dim existingUser = testData.Users.First
    Dim newUserGroup As New UserGroup With {.User = existingUser, .Group = Nothing}
    Dim changes = testData.GetChangeSet()
    testData.SubmitChanges()
End Using

In this snippet there are two required associations: User and Group. As soon as User is set, the UserGroup entity is attached to the DataContext. However, since Group is Nothing the ChangeSet is now corrupt.

This bug is described in this forum thread where a Microsoft employee recommended that he post it on Connect (Microsoft’s bug tracking site). The bug report on Connect can be found here.

LINQ to SQL Gotcha #1: Unexpected LoadWith Behaviour

By default, LINQ to SQL uses deferred loading. When you want to eager load an entity’s associated data you need to set DataLoadOptions using the LoadOptions property on the DataContext. If you have a one-to-many relationship between Users and Articles you can force LINQ to SQL to eager load Articles with Users like this:

Using testData As New TestDataContext
 
    ' Log SQL queries to the console
    testData.Log = Console.Out
 
    ' Set LoadOptions
    Dim options As New DataLoadOptions
    options.LoadWith(Function(user As User) user.Articles)
    testData.LoadOptions = options
 
    ' Load users with their articles
    Dim users = testData.Users.ToList
    For Each user In users
        Dim articles = user.Articles.ToList
    Next
 
End Using

This will generate a single SELECT statement with a JOIN on the Articles table. The same goes for for one-to-one relationships. You can also use LoadWith as many times as you want. For one-to-one relationships and no more than a single one-to-many relationship this will still generate one query with JOINs to all the LoadWith tables. However, if you want to eager load multiple one-to-many relationships you will get into a select N + 1 situation (or worse). For example, this code eager loads Articles and UserGroups with each User entity:

Using testData As New TestDataContext
 
    ' Log SQL queries to the console
    testData.Log = Console.Out
 
    ' Set LoadOptions
    Dim options As New DataLoadOptions
    options.LoadWith(Function(user As User) user.Articles)
    options.LoadWith(Function(user As User) user.UserGroups)
    testData.LoadOptions = options
 
    ' Load users with their articles
    Dim users = testData.Users.ToList
    For Each user In users
        Dim articles = user.Articles.ToList
        Dim userGroups = user.UserGroups.ToList
    Next
 
End Using

Technically, the behaviour here is correct. It will successfully eager load both the Articles and UserGroups collections for each User, but it will not do it in a single query. When I ran this I got one query that fetched the Users and Articles like last time, but then a separate SELECT for each UserGroup rather than another JOIN. Even though this won’t alter the behaviour of the code, it will definitely make a major impact on performance, especially if there are a lot of users in the database.

Scott Guthrie confirmed this behaviour in a post on David Hayden’s blog. This is what he said:

In the case of a 1:n associations, LINQ to SQL only supports joining-in one 1:n association per query.

Lame.