Groups | Blog | Home
all groups > dotnet academic > december 2004 >

dotnet academic : "Synchronized" wrapper



Gilles
12/23/2004 8:47:07 AM
Some classes of .NET framework offer a "Synchronized" static function that
creates a thread-safe wrapper around the object.

example: public static Queue Synchronized(Queue queue)

What is puzzling me is that the returned object is of class Queue too...

It means wrapper is a derived class of Queue but, as a wrapper, it holds a
reference on the original Queue.
As a consequence, the wrapper contains a set of variables issued from base
class Queue that are useless. Don't mind the wasted memory, PC has plenty
of...

Is this scenario right, or did I miss something?
Daniel O'Connell [C# MVP]
12/23/2004 2:38:54 PM

[quoted text, click to view]

Pretty much. Its unfortunate, but its a downside to wrappers in the .NET
design. There is no common baseclass for a Queue.
[quoted text, click to view]

Gilles
12/24/2004 3:11:01 AM
Yep, and it seems to be the same for Match, Group, TextWriter, TextReader,
Stack, SortedList & HashTable classes that all return an object of the same
type.

So, if it is not an "official way" (Synchronized fct is not part of an
interface), it's quite frequent in .NET.

The only difference is ArrayList's implementation that returns an object
implementing an interface (IList) which is more rational.

Otherwise, wouldn't it be more logical to provide directly a xxxSynchronized
derived class rather than providing these wrappers? Is there a recommended
pattern when you intend to write a class that offers both "light" or
thread-safe versions?

More general question: why not directly a thread-safe version?
Daniel O'Connell [C# MVP]
12/24/2004 10:06:23 PM

[quoted text, click to view]

Its the only way, really, as I mention below.
[quoted text, click to view]

Thats because ArrayList's contract is fully expressible using IList, Queue
and many, many others do not.


[quoted text, click to view]

The problem is, you have a variable of type Xxx, and your synced version is
of type XxxSynchronized. Unless XxxSynchronized is derived from Xxx,
XxxSynchronized is pretty close to worthless since you are restricted to
only using a synchronized type in all apis. Therefore you end up with dual
api's, one synced, one not in circumstances where synchronization is not the
API's responsibility, but your own. Too messy, not worth ith.

I would strongly recommend using the same mechanism that the framework uses
when you are doing synchronized wrappers, for synchronized versions you can
simply derive ASynchronized from A and override the methods that need
synchronization.

[quoted text, click to view]

I can't give you quotes, but it is expensive and the cost would be
prohibitive.

Gilles
1/3/2005 2:55:02 AM
I definitely agree with you: the best solution I can see for the problem is
to provide a derived class so that:

class A
{
virtual void fct() {...}
}

class Async:A
{
override void fct()
{
lock(this) { base.fct();}
}
}

But I still wonder why - with Queue for instance - I need to create first an
object of type A and then call a static method of class A to get an Async
Daniel O'Connell [C# MVP]
1/4/2005 3:24:37 AM

[quoted text, click to view]

I tend to agree that it is annoying, however wrappers appear to be the
prefered mechanism for this kind of support, and calling a method allows you
to have syncrhonized and unsynchronized versions running around(whatever
good that'll do ya, it works better with the readonly idiom)

AddThis Social Bookmark Button