Cook Computing

« October 2005 »

VS2005 and NUnit

I downloaded VS2005 yesterday but didn't get around to installing it today (I used the auto-uninstall tool mentioned here). I then tried building and testing XML-RPC.NET. The build went fine but I had a few problems with NUnit.

Starting with NUnit version 2.2.0 already installed on my home machine, the first problem was that by default NUnit does not support version 2.0 of .NET. You need to add a line to the nunit-console.exe.config and nunit-gui.exe.config files to add support for version 2.0.50727 of .NET:

  <startup>
    <supportedRuntime version="v2.0.50727" />
    <supportedRuntime version="v1.1.4322" />
    <supportedRuntime version="v1.0.3705" />
    <requiredRuntime version="v1.0.3705" />
  </startup>

The new line has to be the first child of the <startup> element and I seem to remember that I had to uncomment <startup> in at least one of the config files.

Then when I tried to run a test I got a "Cross-thread operation not valid" error message. To fix this I installed the latest "iteration" build of NUnit - 2.2.2 - after seeing a message from Charlie Poole recommending this for .NET 2.0.

Finally none of my tests were picked up by the test runner. I was relying on test methods being recognized by start with the word "test", e.g. "testInt_NullType" which no longer works out of the box. It now appears to be mandatory to decorate test methods with NUnit.Framework.TestAttribute.

Posted by Charles Cook at 06:45 PM. Permalink. View Comments.

Multiple ItemGroup in MSBuild Projects

Barry's MSBuild session on Saturday was the first time I'd studied an MSBuild project file. I was initially puzzled by the existence of multiple <ItemGroup> elements in a project, for example in a C# project file generated by VS2005 where the references are separate from the source files. I wondered whether this had any significance or was possibly just an artefact of the way the file was generated. After some experimentation it seems that the contents of multiple <ItemGroup> elements are treated as if they were in a single <ItemGroup> element. For example, this project:

<Project DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Reference Include="System" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
works in the same way as this project:
<Project DefaultTargets="Build" 
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Reference Include="System" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

Update: Barry posted a follow-up on his blog, describing scenarios in which you could use multiple ItemGroups.

Posted by Charles Cook at 04:50 AM. Permalink. View Comments.

Second Developer Day

I attended the second DeveloperDeveloperDeveloper day at Microsoft UK on Saturday. Some excellent sessions, in particular I came away fired up to learn more about the following technologies:

  • AJAX (James Crowley gave a very useful introduction to AJAX in .NET)
  • WPF (A very entertaining overview of WPA aka Avalon by Ian Griffiths)
  • MSBuild - (Barry Dorrans maintained a high level of interest in this potentially rather dry subject)
Like the first event, well worth going to, and thanks to everyone concerned.
Posted by Charles Cook at 07:47 AM. Permalink. View Comments.

Testing if Method has params Parameter

XML-RPC.NET does not support methods with a variable number of parameters. I'm currently adding support for this so that a method can be defined like this:

interface IFoo 
{
  [XmlRpcMethod]
  int Foo(params int[] args);
}

This results in the following metadata for the method:

.method public hidebysig newslot abstract virtual 
        instance int32  Foo(int32[] parms) cil managed
{
  .custom instance void [CookComputing.XmlRpc]CookComputing.
XmlRpc.XmlRpcMethodAttribute::.ctor() = ( 01 00 00 00 ) 
  .param [1]
  .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() 
    = ( 01 00 00 00 ) 
} // end of method IFoo::Foo

So I need to be able to determine if ParamArrayAttribute has been defined for a method parameter. I can achieve this using code like this:

Type type = typeof(IFoo);
MethodInfo mi = type.GetMethod("Foo");
ParameterInfo pi = mi.GetParameters()[0];
bool isParams = Attribute.IsDefined(pi, typeof(ParamArrayAttribute));

When serializing the method parameters into an XML-RPC request, if the ParamArrayAttribute is defined on an array parameter I output each member of the array as a separate <param> element instead of a single <param> element containing an array.

Posted by Charles Cook at 06:54 AM. Permalink. View Comments.

Large Monitors

I've seen several links to the NY Times article Meet The Life Hackers mention the benefits of large monitors. Before moving to my current 20" screen at 1600x1200 I tried dual 19" at 1280x1024 but they didn't suit my style of working with Visual Studio. I could not get used to the gap between the screens when I had windows from a single application on both screens (it also didn't help that the machine had been specified with a graphics card which could only support DVI output for one screen and analog for the other; the slight difference in colour rendering was very irritating). 1600x1200 is large enough for me to use Visual Studio comfortably on a single screen but its hardly a big monitor these days. I'd could do with more screen estate for keeping any eye on periodically used applications such as Outlook and Firefox; in particular for looking up something on MSDN when coding. I just saw that Dell are selling some 24" screens with 1920x1200 resolution (£510 plus tax in the UK) and of course Apple have their 30" Cinema Display with a huge 2560x1600 resolution (£1786 plus tax). I wonder how large you can go with a single screen before it is too wide to use comfortably?

Posted by Charles Cook at 06:55 AM. Permalink. View Comments.

Some Myths About Wind Farms

I'm a member of the Ramblers Association in the UK, an organisation which does good work protecting the interests of walkers in England, Scotland, and Wales. The latest newsletter from my local area group contains an article describing some myths about wind farms, a source of energy which the goverment is promoting via massive subsidies. I'll include the myths here as a starting point for further investigation:

Myth 1: They are efficient - wrong. They operate efficiently only when there is a constant wind speed of 30mph and most wind speeds are well below that. Turbines do not work at speeds below 11mph and are shut down for safety above 55mph. Consequently the efficiency of windfarms is about 25%. Power stations, including nuclear, are from 65 to 80% efficient.

Myth 2: Windpower is cheap - definitely wrong. Wind is free but production costs are high, largely due to the inefficiency factor. Developers want to errect new wind farms because government subsidies for construction and operation mean that windpower producers receive over 3 times the market price for their electricty (and all suppliers are obliged by law to buy it).

Myth 3: Windpower is "green" and saves carbon dioxide emissions - not proportionate to the amount of electricity produced. Conventional power stations still have to spin their turbines and produce carbon dioxide, in case there is insufficient wind for wind turbines.

Myth 4: A few turbines will replace conventional power stations - very wrong. Over 2000 of the latest 400 foot high turbines would be needed to replace Ferrybridge power station alone. End on, they would stretch for 280 miles!

Myth 5: Windpower can replace nuclear power stations - wrong. From 13 nuclear power stations 25% of UK electricity is generated. Electricity imported from France is 75% nuclear generated. Nuclear power does not produce any carbon emissions at all, though of course the nuclear waste issue is either a worry problem , or easily contained, depending on whom you listen to .

The government has set targets for reducing greenhouse gas emissions under its Kyoto agreement. One figure, for example, suggests 10% of energy from windpower. To achieve that, 23,000 wind turbines are required, yet they would only reduce carbon dioxide by less than 3% in the UK and 0.02% globally, and these figures do not take into account of the worldwide constantly increasing demand for energy. Government figures suggest that UK demand will have increased by 25% in the next 15 years.

Now, I don't know how accurate these figures are - I need to look into this in more detail - but the government emphasis on windpower as a means of addressing greenhouse gas emissions seems to be me to be nothing more than environmental posturing. If global warming really is the hugely serious threat to our planet that environmentalists suggest, then surely the risks of nuclear power fade into insignificance. I'm sure the windpower policy will be abandoned in a few years but by then huge areas of wild and beautiful countryside will have been devastated because of the government subsidies.

Also, from a strategic point of view, unless we start constructing a new generation of nuclear power stations, in a few years we will become even more dependent on foreign energy sources, for example, Russian gas and French electricity. National security is far more important in my opinion than reducing greenhouse gas emissions by irrelevant amounts.

Posted by Charles Cook at 06:20 AM. Permalink. View Comments.

Fault Containment

James Gosling has a piece on fault containment. Its not a phrase I've used but I've advocated the principle for a long time now, for example using a programming language like C# instead of C or C++, or splitting large applications into multiple processes. He writes:

A lot of what motivated the tight memory model was me having wasted too much of my life tracking down weird exotic memory smashes, and vowing to never have to waste time on stuff like that again.

It puzzles me that I still see people wasting a lot of time on that type of bug-fixing, or observing it from a management point of view, but not making the connection that these problems are almost inevitable with a language like C++ and that development in C++ results in low productivity. Ok, I'm beginning to sound like a broken record but these days I often feel like I'm stuck on one.

Right now I'd like to see fault containment extend down into the implementation of drivers: I've wasted a lot of time recently - yet another hit on productivity - because a set of drivers written by a well known company occasionally bring down the whole OS. Maybe this will be possible one day. An EWeek article quotes researcher Larus on the Singularity project:

We've built an operating system written entirely in C#, all safe code except the kernel and a HAL [hardware abstraction layer] on top," Larus said. "The device drivers and everything else are written in a dialect of the safe form of C#.

I got that last quote from one of the comments to an interesting series of articles by John Siracusa - Avoiding Copland 2010 (plus part two and part three) - where he argues that the lack of a "managed" code programming environment will cause a crisis at some point in the next few years (via Ted Leung who also links to a post by Rainer Joswig; yes, I know that Lisp and Smalltalk had all these problems sorted years ago but I can't see how they will become mainstream; if only Apple had continued development of Dylan).

Posted by Charles Cook at 06:23 AM. Permalink. View Comments.

Older Programmers Working in Bureaucracies

Commenting on Paul Graham's piece on his Summer Founders Program, Philip Greenspun writes:

Graham has introduced some bias into the experiment by hand-picking companies to fund. The teams that he funded were the ones who came to him with the ideas that he liked best. On the other hand, if these guys are succeeding as well as he suggests it must mean that the competition is very weak. Who are the competitors? Older programmers working in bureaucracies at larger companies, which have strong brands and near-infinite capital. So basically what Graham is proving is that these folks are incredibly unproductive and their aggregate work product is almost worthless.

Ouch.

Posted by Charles Cook at 12:40 PM. Permalink. View Comments.

DeveloperDeveloperDeveloper 2

Agenda and sessions for the second DeveloperDeveloperDeveloper event at Microsoft UK are now available. The event is now fully booked but there is a waiting list. If you read this blog or use XML-RPC.NET, please say hello if you see me.

Posted by Charles Cook at 07:36 AM. Permalink. View Comments.

Driven Round the Benz

It depresses me that after a number of years in software development I don't experience much change in the way software is developed. In essence, do some design, knock up some code quickly and then spend a much longer period of time fixing bugs. As well as being soul-destroying its also hugely unproductive. These were my tangential thoughts after reading Driving You Round the Benz in the Independent:

So where did it all go wrong for the maker of "the best cars in the world"? Back in the 1990s, Mercedes manufacturing processes were old-fashioned and cost-intensive. The result was great quality - at great cost. The upshot was also that Toyota, an exemplar at efficient "lean" production, took less time to make a car than Mercedes took to rectify each fully assembled car. If Mercedes was to stay in business, this could not continue.

Except that great quality was never there to begin with in many software products. Where are the Toyota's of the software world we can learn from? TDD seems to offer some hope and I noticed Keith Ray has some links to interesting Uncle Bob pieces on TDD: one, two, three. Martin addresses the issue that it is tempting to fall back into the bad old ways when schedule pressure mounts:

I have been consulting for a number of teams that have adopted Agile Methods, including TDD. One common issue I have found is that developers drop the discipline of TDD in the face of schedule pressure. "We don't have time to write tests" I hear them say. Before I comment on the absurdity of this attitude, let me draw the parallel. Can you imagine an accounting department dropping dual entry bookkeeping because they've got to close the books on time? Even before SARBOX such a decision would be such a huge violation of professional ethics as to be unconscionable. No accountant who respected his profession, or himself, would drop the controls in order to make a date.

That is not to say that accountants don't take shortcuts in the face of schedule pressure. They might not break down all the categories. They might not do all the what-if scenarios. They might bundle some things together that should be split. In other words, they might reduce scope. But would they drop the dual entry practice?

Consider a surgeon who, under schedule pressure, decides not to scrub. Consider a pilot who, under schedule pressure, decides not to go through the checklist. There might sometimes be emergency situations that justify a decision like that; but they had better be extremely rare, life-or-death situations. Even then, the decision is more likely to make things worse than better.

Posted by Charles Cook at 06:52 AM. Permalink. View Comments.

More on .NET Remoting Problem

I didn't have time to investigate the problem I had with RemotingServices.Disconnect. Instead I switched from client-side to server-side sponsorship. I didn't want to modify any of the classes being remoted so I had to find an external way of registering and unregistering class instances for sponsorship.

I created a class to expose the ITrackingHandler interface. The implementation of the MarshaledObject method registers for sponsorship the object being marshaled (for the types for which sponsorship is required). Details of the object are stored in a collection so at any time we know which objects have been sponsored.

Most of the relevant types implement IDisposable (to allow unmanaged resources to be released deterministically) so I use a call to Dispose to indicate that sponsorship should be unregistered. To detect calls to Dispose I implemented a channel sink which examines the message details to determine the method being called, etc. If the method is Dispose, the object has its sponsorship unregistered and its details removed from the collection.

Finally, for objects which Dispose is not called or which don't implement IDisposable, the collection is checked periodically and any members which have been there longer than a configured period of time have their sponsorship unregistered.

This solution has now been running live for two weeks and the leakage of objects on the server has not occurred again. I'm not sure if this is a good general purpose approach but for the constraints of the particular problem it has worked well.

Posted by Charles Cook at 08:30 AM. Permalink. View Comments.