Monday, November 30, 2009

Managed threads in “whole stack committed” shocker

I was experimenting with thread creation in a managed process, to test the limits, and I noticed something very odd.  Creating a large number of threads was using a surprisingly large amount of memory.  I guessed it must be the thread stacks, but the numbers didn’t fit with my understanding of how thread stacks are allocated.  

In an unmanaged process, by default each thread has 1 Mbyte of address space reserved for its stack, but initially only a small amount of this address space is committed.   You can see this with the excellent VMMAP utility – here’s what it shows for an unmanaged x64 application:

unmanaged_threads_x64

The ‘size’ is the reserved address space – 1024k as expected.  The committed memory is 16k, which is the amount of the address space that actually has physical storage associated with it.   This can grow as required, up to the size of the reserved address space, but usually it won’t get close to that. 

The size of the reserved address space is important in the sense that we need to make sure we don’t run out – 2000 threads would be enough to max out a 32-bit process, for example.   But generally speaking it’s the committed size that has more impact - that number has to be backed by real storage, in RAM or at least the page file.

So, back to the managed process.  This is what VMMAP shows:

managed_threads_x64

Reserved address space is the same as before at 1024k, but the whole thing is committed!  So each thread is using the full 1 Mbyte of physical storage, regardless of how much memory the stack actually needs.   That can’t be right, can it?   Well it seems it is, as Joe Duffy explains.

So, the bottom line is that you should think carefully about creating managed threads that are going to sit idle in your process, for example in a thread pool.   In an unmanaged process those idle threads wouldn’t be using many resources, but in a managed process they’re using a significant chunk of valuable memory.   This is even more important if you have any form of multi-process architecture, perhaps with thread pools in each process. 

If you really need a large number of long-lived threads in your managed process, consider reducing the size of the stack using the appropriate overload of the System.Threading.Thread constructor.

Labels: , , ,


Thursday, November 12, 2009

Parallel.For for .NET 3.x

.NET 4.0 includes an interesting class called Parallel, with a For method that allows the iterations of a for loop to be executed concurrently, like this:

Parallel.For(0, 10, i => Console.WriteLine(i));

I’ve done a lot of multithreading over the years, but I must confess it’s never occurred to me to apply concurrency in this way, at the level of a simple for loop.   I’m not sure how often I’ll use it in practice, but my current work project is .NET 3.5 so I wanted to have a .NET 3.x version of Parallel.For to play with.   The code is shown below. 

Some basic tests reveal that at the extremes the performance is not as good as the .NET 4.0 version, but for more common scenarios it seems to be comparable.  

static class Parallel30
{
    public static void For(int fromInclusive, int toExclusive, Action<int> action)
    {
        using (var doneEvent = new ManualResetEvent(false))
        {
            int iterations = (toExclusive - fromInclusive);
            int iterationsCompleted = 0;
            Exception actionEx = null;

            WaitCallback iterationCode =
                (arg) =>
                {
                    try
                    {
                        action((int)arg);
                    }
                    catch (Exception ex)
                    {
                        actionEx = ex;
                    }

                    int completed = Interlocked.Increment(ref iterationsCompleted);
                    if (completed == iterations)
                        doneEvent.Set();
                };

            for (int i = fromInclusive; i < toExclusive; i++)
            {
                ThreadPool.QueueUserWorkItem(iterationCode, i);
            }

            doneEvent.WaitOne();

            if (actionEx != null)
                throw new Exception("Action failed", actionEx);
        }
    }
}

Labels:


Tuesday, November 10, 2009

Unity and primitive constructor arguments

I’m using the Unity IoC container for the first time, and overall I like it.  But one under-documented and slightly unintuitive area caused me some trouble.

Suppose I have a ThreadPool class:

class ThreadPool
{
   public ThreadPool(int maxThreads)
   {
      ...
   }
}

I can register this in the container as follows:

container.RegisterType<ThreadPool>(new InjectionConstructor(20));

So every time the container creates an instance of ThreadPool, it will pass 20 for the maxThreads argument.   It’s not the most intuitive API, but it does the job.

However suppose I now extend my ThreadPool class to add logging, i.e.:

class ThreadPool
{
   public ThreadPool(int maxThreads, ILogger logger)
   {
      ...
   }
}

How do I modify my container registration to inject the correct ILogger instance?  Of course I could just create a Logger instance and pass it as an extra argument to InjectorConstructor, but that’s not the behaviour I want.   I want the container to resolve ILogger when the ThreadPool instance is being resolved.   Having looked through the documentation, I was coming to the conclusion that this wasn’t possible, but then I came across this post on pnpguidance.net that shows how it’s done:

container.RegisterType<ThreadPool>(new InjectionConstructor(20,typeof(ILogger)));

I suppose using typeof in this scenario makes some sense, but it’s hardly intuitive.  The API could be improved so that I don’t need to specify anything about ILogger resolution at all.   I should only have to specify explicitly the constructor arguments that cannot be resolved automatically, e.g.:

container.RegisterType<ThreadPool>().WithConstructorArg("maxThreads", 20);

Labels: , ,


Saturday, October 24, 2009

Managed DCOM server

For my current project I have some old unmanaged C++ code that needs to talk to a new .NET server, remotely.   The channel needs to be fast and secure.   There are a lot of options, but I’ve narrowed it down to two:

  1. WWSAPI for the C++ client, WCF for the .NET server, using NetTcpBinding.  (See here for details.)
  2. DCOM

Option 1 was the strong favourite until Microsoft decided to play silly buggers with the redistribution rights for WWSAPI, so I’ve been forced to investigate option 2.

COM interop through loading .NET components into an unmanaged process is well documented and generally works fine, but accessing a .NET server remotely via (D)COM is not so well documented, and indeed it’s not even clear if it’s supported by Microsoft.   But it does seem to work, and it’s surprisingly simple once you discover the RegisterTypeForComClients method on the RegistrationServices class.   This is basically a wrapper for COM’s CoRegisterClassObject.

Here’s the C# server code:

[ComVisible(true)]
public interface ICalculator
{
    int Add(int x, int y);
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Calculator : ICalculator
{
    public int Add(int x, int y) { return x + y; }
}

class Program
{
    [MTAThread]
    static void Main(string[] args)
    {
        var regServices = new RegistrationServices();

        int cookie = regServices.RegisterTypeForComClients(
            typeof(Calculator),
            RegistrationClassContext.LocalServer | RegistrationClassContext.RemoteServer,
            RegistrationConnectionType.MultipleUse);

        Console.WriteLine("Ready"); Console.ReadKey();

        regServices.UnregisterTypeForComClients(cookie);
    }
}

and the C++ client code:

#import "dcomserver.tlb" no_namespace raw_interfaces_only

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitializeEx(0, COINIT_MULTITHREADED);

    {
        CComPtr<ICalculator> spCalc;
        spCalc.CoCreateInstance(__uuidof(Calculator), 0, CLSCTX_LOCAL_SERVER);
        
        long result = 0;
        spCalc->Add(10, 20, &result);
        
        cout << result << endl;
    }

    CoUninitialize();
    return 0;
}

(The simplest way to generate the tlb file to #import is to run regasm /tlb DcomServer.exe)

There may well be some gotchas with this approach – I haven’t tested it thoroughly yet – but it seems a promising option if the WWSAPI licensing issues can’t be sorted out.

Labels: , , , ,


Monday, October 12, 2009

WCF and abstract types

This seems like a fairly straightforward issue to me, but after googling around I’m left wondering what I’m missing.

Suppose I have a web service that contains a Search() method that takes one of two possible types of query – a simple query or a complex query.   WCF doesn’t support xsd:choice, so I can’t use that, but it does support xsd:extension, so that should do the trick:

    [DataContract]
    [KnownType(typeof(SimpleQuery))]
    [KnownType(typeof(ComplexQuery))]
    class Query { }

    [DataContract]
    class SimpleQuery : Query { }

    [DataContract]
    class ComplexQuery : Query { }

    [ServiceContract]
    interface ISearchService
    {
        Results Search(Query query);
    }

This works ok, but it’s not quite right – the client can pass an instance of Query rather than SimpleQuery or ComplexQuery.   Query really needs to be abstract.   But does XML schema support that?   Yes, it does, through complextype’s abstract attribute.

So, problem solved.  We make Query abstract and WCF’s DataContractSerializer will add the abstract=”true” to the XSD it generates.  Except that it doesn’t.  It just ignores the fact that the Query class is abstract, which means that the client sees the class as non-abstract.  This means that the client can easily pass a Query instance to the server (which of course  causes the serializer on the server to blow up trying to create an instance of the abstract class).   Hmm.

So why doesn’t DataContractSerializer support abstract base classes?  It seems pretty simple, both in concept and implementation.   Presumably it’s deemed too OO-centric … but then why support inheritance (xsd:extension)?  

BTW There’s a StackOverflow question covering the same issue – like the poster I didn’t find any of the answers satisfactory.

Labels: ,


Friday, October 02, 2009

WPF Toolkit DataGrid is an uggo

Update 6-Nov-09:  The style given here works fine for the WPF 4.0 DataGrid (beta 2).

This is the default look for the WPF Toolkit DataGrid:

datagrid1

Ugh.  The black gridlines, the white-on-blue highlight, the cramped text … it’s really not very good.   I’m no graphic designer, but I think the following simple tweaks are a significant improvement:

datagrid2 

The gridlines are trivial to change through the DataGrid’s HorizontalGridLinesBrush and VerticalGridLinesBrush properties.   The selection highlight can be modified by setting the CellStyle property to a style containing a trigger on the IsSelected property of the DataGridCell.  Finally, I added the padding by defining a control template for the cell that has a padded border around the ContentPresenter.   As a little extra I also highlight a row when the mouse passes over it, which I find pleasing to the eye.

Here’s the complete style:

<Style x:Key="PrettierDataGridStyle" TargetType="tk:DataGrid">
    
    <!-- Make the border and grid lines a little less imposing -->
    <Setter Property="BorderBrush" Value="#DDDDDD" />
    <Setter Property="HorizontalGridLinesBrush" Value="#DDDDDD" />
    <Setter Property="VerticalGridLinesBrush" Value="#DDDDDD" />

    <Setter Property="RowStyle">
        <Setter.Value>
            <Style TargetType="tk:DataGridRow">
                <Style.Triggers>
                    <!-- Highlight a grid row as the mouse passes over -->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Lavender" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Setter.Value>
    </Setter>


    <Setter Property="CellStyle">
        <Setter.Value>
            <Style TargetType="tk:DataGridCell">
                <Style.Triggers>
                    <!-- Highlight selected rows -->
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="Lavender" />
                        <Setter Property="BorderBrush" Value="Lavender" />
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </Style.Triggers>

                <!-- Add some padding around the contents of a cell -->
                <Setter Property="Padding" Value="4,3,4,3" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="tk:DataGridCell">
                            <Border Padding="{TemplateBinding Padding}" 
                                Background="{TemplateBinding Background}">
                                <ContentPresenter />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>         
</Style>

Labels: , ,


Thursday, October 01, 2009

.NET FAQ is no more

I was considering an overhaul of my two FAQs, as I haven't really done any work on them for years.   But looking through the .NET FAQ, it became obvious that it would need a total rewrite, and there doesn't seem much point, with all the books and web resources available now.  It served its purpose in the early .NET days (the FAQ was first published in 2000!), but it's time for it to be retired. 

I'll leave the document on the site, so bookmarks will still work, but I've removed all links to it from my home page.  Interesting to see how quickly that affects the search engine ranking - after all these years it's still number one for '.net faq', in both google and bing.

The C# FAQ (for C++ programmers) looks a bit more salvageable, so I'll keep it for now, and aim to give it an overhaul over the next few months.  

Labels: ,


Wednesday, September 23, 2009

Building lambda expressions at run time

Moq is a great library for creating fake objects for use in unit tests. It makes heavy use of lambda expressions to configure the mock, and also to verify that operations have been performed on the mock. For example, suppose we want to verify that the Insert method on an ICache interface has been called:

// Arrange 
var mockCache = new Mock<ICache>();
var someObject = new object();

// Act 
DoSomethingThatShouldAddObjectToCache(mockCache, someObject);

// Assert 
mockCalc.Verify( cache => cache.Insert(someObject) );

The key thing here is the use of a lambda expression in the Verify method. The lambda expression is just a convenient way to create a data structure specifying the method call we’re interested in (ICache.Insert) and the arguments we expect it to be called with (someObject). The Verify method is not going to execute the Insert method call – it’s merely going to examine the lambda expression structure to determine whether it matches a previous call on the mock (which the mock recorded in case we wanted to perform this type of verification).

The use of lambda expressions to package method names and arguments is a concise, typesafe and intellisense-friendly approach, but at first glance it appears to limit dynamic usage at run-time. An example of this problem was recently posted to the Moq discussion forum – the poster wanted to call mock.VerifyGet for every property on an interface, without having to write a VerifyGet call for every property individually.

Obviously reflection can be used to get the properties at runtime, but how do we build the appropriate lambda expression to pass to mock.VerifyGet()? Well, it turns out to be quite straightforward, using the LambaExpression class. The following code builds an expression of the type p => p.Prop, which is what we need for VerifyGet:

ParameterExpression p = Expression.Parameter(mockType, "p");
MemberExpression body = Expression.Property(p, prop);
LambdaExpression expr = Expression.Lambda(body, p);

Wrap this up in an extension method for the Mock<T> class, and we get the following VerifyAllGets() method:

public static void VerifyAllGets<T>(this Mock<T> mock) where T : class
{
    // Get a MethodInfo for the Mock<T>.VerifyGet<TProp> method.
    MethodInfo verifyGetMethod = typeof(Mock<T>).GetMethods(
        BindingFlags.Public | BindingFlags.Instance).Where(
        mi => mi.Name == "VerifyGet" &&
        mi.GetParameters().Length == 1).First();

    // Call the Mock<T>.VerifyGet method separately for each property on T.
    foreach (var prop in typeof(T).GetProperties())
    {
        // Build a lambda expression of the form p => p.Prop
        ParameterExpression p = Expression.Parameter(typeof(T), "p");
        MemberExpression body = LambdaExpression.Property(p, prop);
        LambdaExpression expr = LambdaExpression.Lambda(body, p);

        // Mock<T>.VerifyGet<TProp> must be 'closed' by specifying TProp
        var closedVerifyGetMethod = verifyGetMethod.MakeGenericMethod(prop.PropertyType);

        // Call Mock<T>.VerifyGet(expr)
        closedVerifyGetMethod.Invoke(mock, new object[] { expr });
    }
}

The VerifyAllGets() method can be used as follows:

// Arrange
var mock = new Mock<IManyProps>();

// Act
RunCodeThatGetsAllProps(mock);

// Assert
mock.VerifyAllGets();

Labels:


Wednesday, March 18, 2009

Some cool new(-ish) NUnit features

I haven't looked at NUnit for a long time, and things have moved on a lot since I last used it. I particularly like the support for parameterised tests. For example, the TestCase attribute can be used to specify multiple iterations for a particular test, e.g.:
[TestCase(CalculatorMode.Standard)]
[TestCase(CalculatorMode.Scientific)]
public void TestAdd(CalculatorMode mode)
{
   Calculator calc = new Calculator(mode);
   int res = calc.Add(10,20);
   Assert.That(res, Is.EqualTo(30));
}
This test will be executed twice, once with the calculator in 'standard' mode, and once with the calculator in 'scientific' mode. We can take this a step further and use the Values and Range attributes to expand our set of tests:
[Test]
public void TestAdd(
   [Values(CalculatorMode.Standard, CalculatorMode.Scientific)] CalculatorMode mode,
   [Range(0,5,1)] int x,
   [Range(0,5,1)] int y
   )
{
   Calculator calc = new Calculator(mode);
   int res = calc.Add(x,y);
   Assert.That(res, Is.EqualTo(x+y));
}
This test will run a total of 72 times. The range of x and y are both 0 to 5, with an interval of 1 (i.e. the values 0,1,2,3,4,5), giving 6x6=36 tests, which are then combined with our two modes to give a total of 72 iterations. The multiple iterations show up as separate tests in your test runner, with the names derived from the arguments used for each run, so it's very easy to see what's going on. Also you may have noticed the constraint-based Assert syntax used in the examples above. I was a little unsure of it at first, but it's growing on me. It uses a 'fluent' style to make the Assert more readable, so:
Assert.That(res, Is.EqualTo(x+y));
is very close to the English "Assert that res is equal to x+y". There is a lot of debate about the merits of fluent APIs, but in this context I like it. One constraint that really caught my eye is 'After'. It's useful when testing asynchronous code where you need to wait for a condition to become true. For example:
Assert.That(() => Status, Is.EqualTo("Done").IgnoreCase.After(5000, 50));
What this says is "Assert that status is 'done' (case insensitive) after a maximum of 5 seconds, checking every 50 ms". The chaining of constraints like this is very readable, and the fact that relatively sophisticated constraints like After are built-in is very helpful. (I actually wrote my own version of this asynchronous wait/poll functionality recently, but I can throw it away now and use After instead.) Finally if you derive from the AssertionHelper class, you can cut down the verbosity slightly, and re-write this Assert as:
Expect(() => Status, EqualTo("Done").IgnoreCase.After(5000,50));
Let me know if you've found any other cool NUnit features that I might have missed.

Labels: ,


Tuesday, November 15, 2005

My MSDN bug has disappeared

Logged into the MSDN feedback center today, to see the progress of the ListView bug I reported (see previous blog entry). To my surprise all record of the bug has disappeared. So I used a direct link to the bug, and I got this: Page is hidden This feedback is not being displayed because it may identify a possible security vulnerability. Please re-submit this feedback, and all other security-related issues, at http://www.microsoft.com/technet/security/bulletin/alertus.aspx. Please refer to our FAQ for more details. So apparently the bug is a potential security vulnerability. Actually that makes sense, because it brings the process down. Could easily be due to a buffer overrun or similar issue that could be exploited by a bad guy. The strange thing is that I've heard nothing from MS on this - not even an automated mail saying that my bug was closed. And the message on the web page isn't too encouraging. Do they really expect me to report the problem again via a different web page, after they've apparently wiped my original bug report? Perhaps I should just forget about doing the right thing and cash in?

Labels:


Sunday, November 06, 2005

.NET 2.0 ListView VirtualMode

The Winforms ListView control has a great new feature in .NET 2.0 - virtual mode. Some time ago I wrote a text file viewer (for log files) using .NET 1.1, and I had to hack together my own virtual mode - it worked ok but had a lot of bugs that I never got around to fixing. So I was very happy to be able to ditch all that dodgy code by porting to .NET 2.0. The only problem is that there are a few bugs. I've reported a particularly nasty one via the MS feedback center. If you're using virtual mode and getting apparently random crashes, check that you haven't got any list items containing exactly 260 characters.

Labels: