Archive for March, 2008

Thread-safe repositories

2 commentsWritten on March 25th, 2008 by
Categories: Multithreading, Software Development

First of all, this is not about true DDD repositories... i just needed an in-memory data container with basic storing/retrieving functionality so i figured i'd call it a Repository.

These repositories will be accessed by multiple concurrent threads so i needed to make sure that all access to the underlying dictionary is properly synchronized. But, i also want them to be highly usable and i especially wanted a thread-safe way of dynamically executing queries on them.

Here's what i came up with:

    public class Repository<T> where T : Member

    {

        private readonly object _monitor = new object();

        private readonly Dictionary<Id, T> _members = new Dictionary<Id,T>();

 

        protected object Monitor

        {

            get { return _monitor; }

        }

 

        /// <summary>

        /// any derived classes that use this property are responsible for their own locking!

        /// (use the Monitor property for that)

        /// </summary>

        protected Dictionary<Id, T> Members

        {

            get { return _members; }

        }

 

        public virtual void Store(T member)

        {

            lock (Monitor)

            {

                Put(member);

            }

        }

 

        public virtual void StoreRange(IEnumerable<T> members)

        {

            lock (Monitor)

            {

                foreach (T member in members)

                {

                    Put(member);

                }

            }

        }

 

        public virtual void Remove(T member)

        {

            lock (Monitor)

            {

                if (Members.ContainsValue(member))

                {

                    Members.Remove(member.Id);

                }

            }

        }

 

        public virtual T Get(Id id)

        {

            lock (Monitor)

            {

                if (!Members.ContainsKey(id))

                {

                    return null;

                }

 

                return Members[id];

            }

        }

 

        public virtual T FindFirst(Func<T, bool> expression)

        {

            lock (Monitor)

            {

                return Members.Values.FirstOrDefault(expression);

            }

        }

 

        public virtual IEnumerable<T> FindAll(Func<T, bool> expression)

        {

            lock (Monitor)

            {

                return Members.Values.Where(expression).ExecuteImmediately();

            }

        }

 

        /// <summary>

        /// this method should ONLY be called when a lock on Monitor has been acquired!

        /// </summary>

        /// <param name="member"></param>

        private void Put(T member)

        {

            // this overwrites existing entries with the same ID... it's not a mistake ;)

            Members[member.Id] = member;

        }

    }

each access to the dictionary is properly synchronized (at least, i think so... if anyone knows of a better way to do the locking, please leave a comment) and i can still execute dynamic queries on them by passing lambda expressions to the FindFirst and FindAll methods, like this:

            User me = userReposority.FindFirst(u => u.FirstName == "Davy" && u.LastName == "Brion");

            IEnumerable<User> usersWithNoLastName =

                userReposority.FindAll(u => string.IsNullOrEmpty(u.LastName));


got memory?

No Comments »Written on March 25th, 2008 by
Categories: Off Topic

build notification memory usage

this is for the Build Notification power tool for TFS 2008. 34 megs of RAM... for a little system tray icon that notifies you when a build has started/stopped. And it's only watching 3 builds. 34 megs of RAM. Unbelievable...

why oh why does visual studio create multiple .vsmdi files?

No Comments »Written on March 20th, 2008 by
Categories: Rants

I'm forced to use MSTest at work... i had to use it at a previous client, hated it then and i still hate it now (even though the 2008 version is a lot faster than the 2005 version).

One of the things that bugs me the most is the .vsmdi file it creates, or better yet, the fact that it keeps creating vsmdi files even though i already have one! I'm sure anyone who's ever worked with MSTest has experienced this issue.

I'd be very grateful to hear answers to the following questions:

1) Why can't it simply use the already existing .vsmdi file? 2) Why oh why has this problem been there ever since the 2005 version was released? 3) Why can't they fix this? i can't imagine this being a hard bug to fix... and i definitely can't imagine needing more than 3 years to fix this 4) Is there anyone within Microsoft who's actually used this crap? 5) Why should i use MSTest over the NUnit/TestDriven.NET combo? Obviously, Microsoft can't even get the integration with its own product right.

Oh and before you ask, you can even get this problem without using source control or read-only files, so please don't suggest that might be the reason :)

Another use for extension methods

No Comments »Written on March 18th, 2008 by
Categories: Software Development

i'm not a huge fan of extension methods, allthough they certainly can be useful at times. I'm using lambda expressions on collections that can be accessed by concurrent threads, and as you may or may not know, lambda expressions usually aren't executed until you iterate over the results. But my collections need to be locked while the expression is executed, so i really need to make sure they are executed immediately (before my lock is released). An easy way to do it is to just use the .ToList() method on the resulting IEnumerable. But that really looks weird because it really doesn't show the intent of what you're trying to do.

So I defined the following extension method:

    public static class Extensions

    {

        public static IEnumerable<T> ExecuteImmediately<T>(this IEnumerable<T> enumerable)

        {

            // in case of an IEnumerable<T> that is the result of a lambda expression, the

            // expression might not have executed yet (deferred execution). In this application

            // we'll be executing a lot of lambda expressions on collections that need to

            // be synchronized, so we need to make sure those lambda expressions are executed

            // immediately, while the lock on the parent collection is maintained.

            // Simply returning a .ToList() of the enumerable will make sure that the lambda

            // expression is executed immediately and the result is valid.

            // Should the creation of a new List<T> prove to be too expensive, we only need to

            // modify the line below to use a faster approach and the entire application would

            // benefit from it

            return enumerable.ToList();

        }

    }

and now i can do this:

            lock (_parentsLock)

            {

                return _parents.Where(p => String.IsNullOrEmpty(p.Path)).ExecuteImmediately();

            }

Which clearly shows the intent of what is being done.

Encapsulating collections

No Comments »Written on March 17th, 2008 by
Categories: Software Development

When i have classes that need to expose collections, i always try to make sure that consumers only get a read-only version of that collection. Consumers should be able to easily use those collections, but if something would need to be added or removed from a collection, it should happen with a specific call to the owner of that collection instead of manipulating the collection directly. In .NET 2.0 i often used the ReadOnlyCollection class for this, but now with .NET 3.5 there is a much easier way. By simply exposing the collections as IEnumerable you prevent consumers from directly adding or removing items from your collection, but with the LINQ extension methods, they are still very usable to anyone that need to use them.

Small example:

    public class Member

    {

        private readonly List<Member> _parents;

        private readonly List<Member> _children;

 

        public Member()

        {

            _parents = new List<Member>();

            _children = new List<Member>();

        }

 

        public IEnumerable<Member> Children

        {

            get { return _children; }

        }

 

        public IEnumerable<Member> Parents

        {

            get { return _parents; }

        }

 

        public void AddChild(Member child)

        {

            _children.Add(child);

        }

 

        public void RemoveChild(Member child)

        {

            _children.Remove(child);

        }

 

        public void AddParent(Member parent)

        {

            _parents.Add(parent);

        }

 

        public void RemoveParent(Member parent)

        {

            _parents.Remove(parent);

        }

    }

the Parents and Children collections are completely encapsulated, yet still highly usable to consumers:

usableencapsulatedcollection.png