Tuesday, March 31, 2009

Strong Name Verification on Windows 2k8 x64

I recently was trying to disable strong name verification on a Windows Server 2008 x64 machine. I ran the standard:
sn.exe -Vr *

which didn't seem to work. It turns out, and I have no idea why. You need set the regkey directly to make this work.

To disable strong name verification for all dlls on a machine (which is a terrible idea in most cases) add:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,*]


to the registry.

Saturday, March 7, 2009

A couple of ways to screw up your parallization

I had a function that needed to call a couple of long running operations.  The function has gotten unacceptable slow.  So the obvious thing to do was to thread the operations to run in parallel.  No problem, couple of lines of code and we'll be all set.  First draft:

Dictionary<Action<object>, int> functionsAndArguemnts = new Dictionary<Action<object>, int>

{

    {this.LongRunningOp1,1},

    {this.LongRunningOp2,2},

    {this.LongRunningOp3,3},

};

 

functionsAndArguemnts.Keys.Select(key =>

    {

        Thread t = new Thread(new ParameterizedThreadStart(key));

        t.Start(functionsAndArguemnts[key]);

        return t;

    }).ToList().ForEach(thread=>thread.Join());


This showed no performance improvement.  I was surprised for a second and then, thankfully I figured it out.  I was a victim of the power of the yield return.  The select will yield return the results and so each thread would only start when we tryed to join to it. Doh!  Easy enough to fix though:


functionsAndArguemnts.Keys.Select(key =>

    {

        Thread t = new Thread(new ParameterizedThreadStart(key));

        t.Start(functionsAndArguemnts[key]);

        return t;

    }).ToList().ForEach(thread=>thread.Join());


So the next way I screwed up my parallization was a bit less subtle.  I had a function that handled all the synchronization and error handling (the error handling bit I left out of this example) for some threading I was doing.  It takes in a function and a argument and calls the function with the argument and then puts all the results in a list.


private List<int> ints = new List<int>();

public void DoStuff(Func<string, IEnumerable<int>> action, string argument)

{

    lock (this.ints)

    {

        this.ints.AddRange(action(argument));

    }

}


Once again, silly me.  No parallization is happening.  And once again easy fix:


public void DoStuff(Func<string, IEnumerable<int>> action, string argument)

{

    IEnumerable<int> results = action(argument);

    lock (this.ints)

    {

        this.ints.AddRange(results);

    }

}


The moral of the story, parallization is still hard.


An interesting link on some lock trivia that highlights the point:  Locks and exceptions don't mix.

I am looking forward to the work in C# 4.0 around threading, would make some things simpler.