views:

75

answers:

3

I've got a static variable (abstract data type, not a primitive) in my C# ASP.NET project.

It will be read by many threads, concurrently and frequently.

I need to write to it very rarely (compared to number of reads).

What is the best way of ensuring threadsaftey so that whilst im writing to it, other threads aren't reading partially-written data?

I've only ever used lock, but i understand this will prevent concurrent reads :(

Thanks

+1  A: 

You can use the ReaderWriterLock, which is more difficult to use than lock, but it allows concurrent reads: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

chris166
+5  A: 

I'd start off just with lock. Uncontested locks are very cheap. You could use ReaderWriterLockSlim (assuming you're using .NET 3.5) but a lock is simpler to get right. Optimise it if/when it becomes a problem.

Straight ReaderWriterLock may well be slower than the simple lock - it's not as fast as it might be, hence the slim version :)

Just how frequently do you mean by "frequently"? How much contention do you expect? You might want to model it (e.g. simulate a reasonable number of requests) and benchmark no locking vs simple locking, just to see what the overhead is.

You may be able to use the lock-free option of volatile - but frankly I've recently given up on that as too hard for sane people to reason about. (It doesn't mean what I thought it meant.)

What are you actually doing with the data? Is the type an immutable type, so once you've got the right reference, you can read in a thread-safe way without any locking?

Jon Skeet
Good advice- that is one of oddities in the .NET framework that unless you read about it you might end up making the wrong choice.
RichardOD
@Andrew- here's a good article if you want to read more about it- http://blogs.msdn.com/pedram/archive/2007/10/07/a-performance-comparison-of-readerwriterlockslim-with-readerwriterlock.aspx
RichardOD
thanks for the advice. I'll be reading on every request, so as frequently as there is traffic. writing will in the order of once a day.
Andrew Bullock
i think ive overlooked the immutability aspect. at the moment its not (but could be) so locking doesnt really help me. Hmm, time for a rethink. If i made it immutable perhaps i wouldn't need any locking as requests can just take a copy
Andrew Bullock
@Andrew: You'd still need to either lock or make it volatile, to avoid getting stale data.
Jon Skeet
yeah i realise that, last comment didnt end up saying what i meant. I've posted my solution below
Andrew Bullock
A: 

Thanks for your help people, I've settled on this approach until performance becomes an issue. Presumably this is correct (threadsafe), where SharedResource is immutable

public static class SharedResourceManager
{
    private static readonly object syncLock = new object();

    private static SharedResource res { get; set; }

    public static SharedResource Resource
    {
     get
     {
      lock (syncLock)
       return res;
     }
     set
     {
      lock(syncLock)
       res = value;
     }
    }
}
Andrew Bullock
Yes, that's safe. Using a volatile private variable would probably be okay too. Any reason you're using a property at all for `res`, given that it's private?
Jon Skeet
thanks for the help :) no reason, removed it ;)
Andrew Bullock