An aggregation of all the Rock Solid Knowledge Blogs
Just finished DevWeek 2009
It's been another great week. Spent time with people I haven't seen for a while. I've enjoyed giving the talks and hope you have enjoyed listening to them. I always love spending time hanging out the speakers, there are so many really smart people there. Just spent a day with Tim Ewald - it always blows me away how good a presenter Tim is and how much he knows, this time on Ruby and Rails.
Hopefully I'll be back for Software Architect in Sept/Oct and at DevWeek next year.
Thanks to all who attended my Devweek session: A Beginners Guide to Windows Workflow. The slides and demos can be downloaded here
If you look in the System.Threading namespace you will notice something that looks slightly odd: there are a pair of classes ReaderWriterLock and ReaderWriterLockSlim. What are these for and why are there two of them?
Whenever you have multiple threads there is a need to protect state shared between them from corruption. The simplest tool in the .NET Framework is the Monitor class (encapsulated by the lock statement in C#) that provides mutual exclusion. In other words, only one thread at a time can acquire it and anyone else trying to acquire it blocks until the first thread releases it. It situations of high update this provides a reasonable approach. However, if we had no writers we could allow everyone to access a resource without acquiring a lock. So if we had many readers and only an occasional writer, ideally we’d like all the readers to be able to access a resource at the same time and only be blocked if someone needed to write. Unfortunately a Monitor would only allow one reader in at a time so this is the role of a Reader/Writer lock – to allow many concurrent readers but only a single writer, blocking all readers.
So we come to the next question: why are there two of them? ReaderWriterLock was introduced in version 2.0 of .NET and provided the above functionality. However, there was a problem. Imagine this scenario: we have 10 readers currently reading when a writer wants access. Obviously the writer has to let the readers finish and so waits patiently for the readers to release their read locks. However, as the readers drop to one, suddenly a brand new reader arrives – there i still a read lock being held but thats ok as it can also acquire a read lock in that situation. Now the writer is blocked on a new reader and more can continue to arrive so that the writer never gets in – this is called writer starvation. ReaderWriterLock suffers from the possibility of writer starvation.
For version 3.5 SP1 the .NET framework team decided to address this. They introduced a new class called ReaderWriterLockSlim that provides the reader/writer lock functionality but does not suffer from writer starvation (new readers are blocked when there is a writer waiting). However, why didn’t the team just fix the original one? They say that some people depend on the feature that new readers can get a lock if a reader is already there. They didn’t want to break existing code.
The .NET Async pattern is a very neat way of running functionality asynchronously. The async pattern is where for a synchronous method DoWork be have a pair of methods BeginDoWork and EndDoWork to handle running the DoWork functionality on the threadpool. Now it is well documented that if I call the Begin method I must also call the End method to allow the async infrastructure to clean up resources it may have acquired. However, where do I call the End version?
Consider async delegate invocation. Quite often I’d like to just fire off the async method and forget about it but I have to call EndInvoke. Fortunately lambdas make this really easy
Action a = DoWork;
a.BeginInvoke( ar => a.EndInvoke(ar) );
Now there is a nasty problem. What happens if DoWork throws an exception? The async delegate infrastructure will conveniently cache the exception and re-throw it when I call EndInvoke. However, the issue is that this is happening in an AsyncCallback delegate on a threadpool thread and so I cannot catch it easily in this construct. Why is that a problem? well since .NET 2.0 an unhandled exception on a background thread will terminate the process. This means to reliably call EndInvoke in an AsyncCallback we must put it in a try … catch. This is annoying code to reliably put in place and is easily forgotten. So I have written an extension method to wrap this functionality for you
public
static class
Extensions
{
public static
AsyncCallback Try(this
AsyncCallback cb, Action<Exception>
exceptionAction)
{
AsyncCallback wrapper = delegate(
IAsyncResult iar)
{
try
{
cb(iar);
}
catch
(Exception e)
{
exceptionAction(e);
}
};
return
wrapper;
}
}>
So this code extends AsyncCallback and takes a delegate to call if an exception takes place it then wraps its own AsyncCallback around the one passed in this time putting it in a try … catch block. The usage looks like this:
Action a =
DoStuff;
AsyncCallback cb = ia
=> a.EndInvoke(ia);
a.BeginInvoke(cb.Try(e => Console.WriteLine(e)), null);>
The only awkward thing here is having to take the lambda out of the call to BeginInvoke because the C# compiler won’t allow the dot operator on a lambda (without casting it to an AsyncCallback) but at least this wraps up some of the issues
>>When you add a VSTS load test or when you configure a web test you can specify the browser(s) to use for the test. The data for each type of browser is held in files with a .browser extension in the C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Templates\LoadTest\Browsers directory.
You can add your own browsers to this list by copying and renaming one of these files and changing the details within the file. The files are XML so this is easy to do, they look something like this
<Browser Name="Netscape 6.0">
<Headers>
<Header Name="User-Agent" Value="Mozilla/5.0 (Windows; U; Windows NT 5.0; en; rv:1.0) Netscape/6.0" />
<Header Name="Accept" Value="image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*" />
<Header Name="Accept-Language" Value="{{$IEAcceptLanguage}}" />
<Header Name="Accept-Encoding" Value="GZIP" />
</Headers>
</Browser>
Remember to change the Name attribute on the Browser element otherwise you'll see the same browser listed twice inside visual studio.
After making the changes you will need to re-start Visual Studio to see your new browser listed.
I talked about the new WF4 Runtime model a while back. One of the things I discussed was the new data flow model of arguments and variables. However, if you are used to WF 3.5 something looks a bit odd here. Lets look at a simple activity example:
public
class WriteLineActivity : WorkflowElement
{
public
InArgument<
string> Text { get; set; }
protected
override
void Execute(ActivityExecutionContext context)
{
Console.WriteLine(Text.Get(context));
}
}
Why do I need to pass the
ActivityExecutionContext when I want to get the data from the
argument? This highlights a subtlety to the change in the runtime
model. The activity is really just a template. A class called
ActivityInstance is the thing that is actually executed, it just
has a reference to the actual activity to be able to hand off to
the activty’s methods (e.g. Execute). The actual argument state is
stored in a construct called the LocalEnvironment. The
ActivityExecutionContext gives access to the current
ActivityInstance and that in turn holds a reference to the current
LocalEnvironment. Therefore, to get from an activity’s
Execute method to its state we have to go via the
ActivityExecutionContext.
I’ve finally got round to pushing the code for BlobExplorer to CodePlex. You can find the CodePlex site here. If you want to contribute to the project, let me know at richard at nospam dotnetconsult dot co dot uk and I’ll add you to the contributors list. The releases will continue being pushed to blob storage http://dotnetconsult.blob.core.windows.net/tools/BlobExplorer.zip
A while back I did this post talking about how WCF contract definitions should model the messages being passed and not use business objects. This inevitably means that you have to translate from the Data Transfer Object (DTO) in the contract to business object and back again. This can feel like a lot of overhead but it really does protect you from a lot of heartache further down the line.
However Dom just pointed out the AutoMapper to me. This is in its early stages but looks like the kind of library that will really take away a lot of the grunt work associated with using DTOs – kudos!
I've just dropped a new release of Blob Explorer for managing Windows Azure Blob Storage
Two new features:
As always you can get it from blob storage here
http://dotnetconsult.blob.core.windows.net/tools/BlobExplorer.zip