Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / April 2005

Tip: Looking for answers? Try searching our database.

Windows Service

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Shawn B. - 19 Apr 2005 18:56 GMT
Greetings,

I couldn't find a more appropriate NG so I thought I'd post my question
here.

Lets say I have a Windows Service that has some object instances I want to
use in my application process.  How would I go about requesting an object
instance from the service, and can I move the object into my process?  Will
I have to marshal everytime I make a call or read a property?

Thanks,
Shawn
Sean Hederman - 19 Apr 2005 22:13 GMT
> Greetings,
>
[quoted text clipped - 6 lines]
> Will
> I have to marshal everytime I make a call or read a property?

You have 2 main options here, you can make the objects inherit from
MarshalByRefObject (marshalling by reference) or have the
SerializableAttribute defined on them (marshalling by value). If you marshal
by reference, then the objects remain in their AppDomain and any call across
these boundaries will result in the call being marshalled. If you marshal by
value then a copy of the object(s) will be marshalled over to the calling
AppDomain. These copies can then be operated on locally. Keep in mind that
the "local" copy will no longer be in the services AppDomain and will thus
have to communicate with the service via Remoting (or similar) if they need
to use capabilities there.

> Thanks,
> Shawn
Shawn B. - 19 Apr 2005 22:30 GMT
Hmm... looks like I'll have to keep the MarhsalByRefObject option... because
these objects that I'll need a pointer to exists in its own thread.

> > Greetings,
> >
[quoted text clipped - 20 lines]
> > Thanks,
> > Shawn
Sean Hederman - 20 Apr 2005 06:00 GMT
> Hmm... looks like I'll have to keep the MarhsalByRefObject option...
> because
> these objects that I'll need a pointer to exists in its own thread.

Objects don't exist in a thread, they cross thread boundaries. So I think
what you mean is that they were created in their own thread. This is not a
problem however, since marshalling by value means they will be serialized
across into the calling threads context (and then be available to all
threads in that AppDomain), and marshalling by reference means that they
will either be called in the calling threads context, or in a threadpool
context.

>> > Greetings,
>> >
[quoted text clipped - 28 lines]
>> > Thanks,
>> > Shawn
Shawn B. - 20 Apr 2005 18:02 GMT
I suppose I'll just say what it is I'm doing.

I created an object pool, and anything can be pooled that supports the
IPoolableObject interface.  I have some requirements, and it must be pure
.NET component, no COM+.

The pool works awesome, its really neat.  It is also very low overhead
(currently).  The problem that I'm foreseeing (but not encountering yet) is
that this will be used to pool some medium-lightweight business objects and
a lightweight data access component that gets created and destroyed
thousands of times per second on our web application site.  By light -
medium weight, I mean these things take about ~1 - ~5 milliseconds each to
be created but are almost immediately destroyed.  Heavy objects should
probly be pooled also, but those heavy objects/operations are usually
already offloaded into a message queue and executed elsewhere.

Thus, I can foresee threading issues if I keep the objectpool in the
Application collection, when each page requests it, I'm thinking the object
instances will each sit in the same thread and won't be executing
simultaneously.  Now, this ObjectPoolManager is a type of factory.  When I
can ObjectPool.GetInstance() it will look for an available instance in the
pool or create a new one and adds it to the pool.  There's a few details I'm
leaving out but thats the jist.

My concern is that I'll end up contending for resources that all exist on
one thread so I've created a custom threadpool (I'm not happy with the .NET
Threadpool) to help out here.

Somewhere along the line I feel that I should just move this into a service
so that way it can use its own threadpool but if I keep it the way it is
now, I can create as many objectpools as I want and that could lead to
problems.  However, this is intended to be used in our high volume webserver
and services.  Any 15 second of the working day we have about 30,000
requests (not on the same server).

Thanks,
Shawn

> > Hmm... looks like I'll have to keep the MarhsalByRefObject option...
> > because
[quoted text clipped - 40 lines]
> >> > Thanks,
> >> > Shawn
Sean Hederman - 20 Apr 2005 21:51 GMT
>I suppose I'll just say what it is I'm doing.
>
[quoted text clipped - 23 lines]
> I'm
> leaving out but thats the jist.

As I was trying to say, objects don't sit on a given thread, they cross
thread boundaries. This is where multithreading issues come from. If you
have an ObjectA created in Thread1, then it's constructor will run in that
context. If you then call it from Thread2, then the method being called will
execute in the context of Thread2. If you simultaneously call it from
Thread3, then you could have a concurrency issue since both Thread2 and
Thread3 can now change the object data and cause a race condition.

However, if Thread2 and Thread3 are in a separate AppDomain from where
ObjectA was created, you can avoid this by making ObjectA marshal by value.
Now, Thread2 will receive a copy of ObjectA and Thread3 will receive a
different copy of ObjectA. If ObjectA is marshalled by reference, then
Thread2 and Thread3 will be accessing the same object (which has remained in
it's original AppDomain) and you will have the same concurrency issues as if
Thread1, 2 and 3 are in the same AppDomain.

> My concern is that I'll end up contending for resources that all exist on
> one thread so I've created a custom threadpool (I'm not happy with the
> .NET
> Threadpool) to help out here.

What is your concern with the .NET Threadpool? It's a pretty efficient
implementation. Also, if you're marshalling across AppDomains you are
generally using threads from the .NET Threadpool. Using my example above,
with ObjectA being marshalled by reference, when Thread2 calls ObjectA, the
remoting message crosses the AppDomain boundary where it is intercepted by
the Remoting infrastructure in the server AppDomain. The remoting system
then allocates a thread from the .NET threadpool to service the request
(i.e. it is not serviced by Thread1).

> Somewhere along the line I feel that I should just move this into a
> service
[quoted text clipped - 4 lines]
> and services.  Any 15 second of the working day we have about 30,000
> requests (not on the same server).

If you're storing your object pools in Application, then you definately have
a concurrency issue. In this case the "client" threads are in the same
AppDomain as the "server" objects. Thus the whole marshal by
reference/marshal by value options don't come up. In such a case (or a MBR
case), you will have to either:
- a) Put concurrency code into your objects, allowing them to be used across
threads.
- b) Put concurrency code into your object pool, ensuring that each object
provided by it is only used in one thread at a time.

With option b, you could have code where your request for an object removes
it from the list of available objects in the pool, and then the caller
returns it to the pool when it is finished with it.

Also, keep in mind that those of your objects that are not changed after
being placed in the pool do not need concurrency code.

> Thanks,
> Shawn
[quoted text clipped - 49 lines]
>> >> > Thanks,
>> >> > Shawn
Shawn B. - 20 Apr 2005 23:43 GMT
> If you're storing your object pools in Application, then you definately have
> a concurrency issue. In this case the "client" threads are in the same
[quoted text clipped - 9 lines]
> it from the list of available objects in the pool, and then the caller
> returns it to the pool when it is finished with it.

I'm going to use option b).  The way I have it implemented is that the
object remains in the pool, or, more precisely, the ObjectPool manager still
has knowledge of the object via WeakReference so that if the Target == null
then the ObjectPool manager will reclaim it back into the pool.  In reality,
I don't wan that to happen; instead I want the consumer to call
IPoolableObject.Recycle() which will in turn put the object back into the
pool.

I'm not certain right now one way or the other whether it is good or bad
design to have the pool still try to track it through the WeakReference as a
last ditch effort to keep resources under control (it checks by default once
every 5 seconds but can be changed).

It works really well except in ASP.NET.

I am implementing a ThreadPool in the ObjectPool and each IPoolableObject
will operate in its own thread (thats what I'm aiming for, as you point out
in B.).

Perhaps when I get the threading worked out I can upload it somewhere and
you can look at it if you want.

BTW: This is all in 2005 using generics.  I don't have the object pool
containing multiple objects yet, instead, you instance an
ObjectPool<ObjectType> but in the end I want one pool to be able to support
multiple object types.

Thank you for your help.

Thanks,
Shawn
Sean Hederman - 21 Apr 2005 05:54 GMT
> I'm going to use option b).  The way I have it implemented is that the
> object remains in the pool, or, more precisely, the ObjectPool manager
> still
> has knowledge of the object via WeakReference so that if the Target ==
> null
> then the ObjectPool manager will reclaim it back into the pool.

This is too late, Target == null means that the object has been collected by
a GC and no longer exists. You cannot therefore reclaim it, unless you mean
you'll recreate a copy in that instance? However in this scenario, Target
might not become null for quite some time. If your pool only creates a
certain number of a particular object, this could lead to resource
starvation.

> In reality,
> I don't wan that to happen; instead I want the consumer to call
> IPoolableObject.Recycle() which will in turn put the object back into the
> pool.

Doesn't that mean that the object has to know how to put itself back in the
pool? Wouldn't it be better for encapsulation to have an
ObjectPool.Reclaim(object) method instead?

> I'm not certain right now one way or the other whether it is good or bad
> design to have the pool still try to track it through the WeakReference as
> a
> last ditch effort to keep resources under control (it checks by default
> once
> every 5 seconds but can be changed).

Rather than try to track every copy out in the wild, how about tracking
every object in you pool. Let's say you want 5 copies of ObjectA, your pool
creates them. 3 of them get handed out to other procesees. A few seconds
later, 1 gets returned. Now your "pool management" function kicks in. It
analyzes the pool and determines that it is 2 short on ObjectA, so it
creates 2 and adds them to the pool. Now one of the "old" ObjectA's is
returned, the pool looks and sees that it already has 5, and therefore
destroys the incoming one. It then gives out one of it's copies, and then
another "old" object A returns, which it places back in it's pool.

> It works really well except in ASP.NET.
>
> I am implementing a ThreadPool in the ObjectPool and each IPoolableObject
> will operate in its own thread (thats what I'm aiming for, as you point
> out
> in B.).

I'm really unsure of what you mean here. Is the ObjectPool a service that
polls sockets? Is the ObjectPool in a different AppDomain? Surely, the
ObjectPool and IPoolableObjects will operate in the Thread that is using
them rather than their own thread?

> Perhaps when I get the threading worked out I can upload it somewhere and
> you can look at it if you want.

Sure.

> BTW: This is all in 2005 using generics.  I don't have the object pool
> containing multiple objects yet, instead, you instance an
> ObjectPool<ObjectType> but in the end I want one pool to be able to
> support
> multiple object types.

class ObjectPool {
   ...
   public T GetObject<T>() {
       ...
   }

   public void ReturnObject<T>(T @object) {
       ...
   }
}

> Thank you for your help.

No problem.

> Thanks,
> Shawn
Shawn B. - 21 Apr 2005 18:15 GMT
> > I'm going to use option b).  The way I have it implemented is that the
> > object remains in the pool, or, more precisely, the ObjectPool manager
[quoted text clipped - 9 lines]
> certain number of a particular object, this could lead to resource
> starvation.

Actually, my object isn't in the pool, an internal object that hold a
reference to an instance of my object is in the pool, along with state
information (active, available, unknown).  When WeakReference.Target ==
null, then this container object creates another instance and marks it as
available (if the pool wants to have n number of object in the pool at all
times, by default, the pool grows and shrinks according to demand).  If in
onDemand mode, then when the Target == null, then the container object gets
removed from the pool.

> > In reality,
> > I don't wan that to happen; instead I want the consumer to call
[quoted text clipped - 4 lines]
> pool? Wouldn't it be better for encapsulation to have an
> ObjectPool.Reclaim(object) method instead?

Ah... yes.  Details details.  When the pooled object gets created, a
reference to the pool that created it gets passed in (in the constructor ::
potential circular reference? potentially)... so when you call
IPoolableObject.Recycle it actually calls ObjectPool.Recycle(this) for you.

> > I'm not certain right now one way or the other whether it is good or bad
> > design to have the pool still try to track it through the WeakReference as
[quoted text clipped - 24 lines]
> ObjectPool and IPoolableObjects will operate in the Thread that is using
> them rather than their own thread?

No, object pool does not poll sockets.  It is actually just another type of
a collection (it derives from System.Object) and initially, I intended it to
be in the same AppDomain and it currently is.  The reason I say that is
because its primary use will be in an ASP.NET web application.  I want each
object (up to a certain limit) to be in its own thread or I'l have all the
web pages contending for an object pool the lives in the Application
variable (not sure where else to put it besides in a Service and marshal
it).  The second place it will be used will be in our backend service
servers, since we have many services that do many different things, but this
object pool doesn't solve every problem and won't be the right thing to use
in all services.  Just where it makes sense.

> > Perhaps when I get the threading worked out I can upload it somewhere and
> > you can look at it if you want.
[quoted text clipped - 24 lines]
> > Thanks,
> > Shawn

Thanks,
Shawn
Sean Hederman - 21 Apr 2005 23:09 GMT
> Ah... yes.  Details details.  When the pooled object gets created, a
> reference to the pool that created it gets passed in (in the constructor
> ::
> potential circular reference? potentially)

Not a problem in .NET thank goodness ;D

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.