The two things are unrelated; making the user-defined class thread-safe will
protect against threaded operations on the instances of the user-defined
class; making the container thread-safe will protect against threaded
operations on the container.
The real question is: what are you going to be doing with the container? If
it is populated once, and then left alone (i.e. no Add / Remove / {reassign
element}), then you are probably OK. However, if the container contents
change, then you must make the container thread-safe. Otherwise the
following can fail:
if(!container.Contains(myUser)) {
container.Add(myUser);
}
This can fail if another thread is doing something similar, and inserts
myUser after you checked (Contains) and before you added (Add). You could
get around this by locking, but then - yes - you get a pinch-point. You can
mitigate this by minimising the time holding locks, e.g. (assuming I have
wrapped the container and exposed a SyncLock):
lock(container.SyncLock) {
SomeUnrelatedMethodThatDoesntAffectContainer();
UserClass myUser = container[17];
myUser.SomeLongOperation();
}
should be written:
SomeUnrelatedMethodThatDoesntAffectContainer();
UserClass myUser;
lock(container.SyncLock) {
myUser = container[17];
}
myUser.SomeLongOperation();
Another option is to look at reader/writer locks. Some sing thier praises;
personally I like to keep it simple and just use a standard lock; as long as
you minimise the lock time you generally get plenty of performance.
Marc