sharing a global object - threading issues

  • Thread starter Thread starter wh
  • Start date Start date
W

wh

I really just need some reassurance that I'm doing the right thing really.
Here goes...

I have an object which needs to be available to all sessions. This is being
created in the Application_OnStart() event. Once created the object is
stored in the Application collection.

The idea of this global object is to manage resources (xml files) between
different sessions/users.

For example user #1 may require write access to file1.xml. If user #2
requests write access to the same file then the request will be denied. The
global object will have a method such as IsPageInUse() which will check
whether the requested page is already in use (I intend to store this
information in a collection) and return true/false accordingly.

What I'd like to know is how much support would I need to include in the
IsPageInUse() method to handle calls from multiple pages? I assume that
multiple calls can be made into the function (as opposed to one at a time
like with STA COM objects) and I will therefore need to add code to ensure
there are no race conditions when checking whether pages are in use, etc.

Thank you,
Wayne.
 
I don't know anything about your IsPageInUse method, so I can't answer that
specific question. However, you should be storing your class in the
Application Cache if you want full threading support.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
http://www.takempis.com
Big Things are made up of
Lots of Little Things.
 
wh said:
I really just need some reassurance that I'm doing the right thing really.
Here goes...

I have an object which needs to be available to all sessions. This is being
created in the Application_OnStart() event. Once created the object is
stored in the Application collection.

The idea of this global object is to manage resources (xml files) between
different sessions/users.

For example user #1 may require write access to file1.xml. If user #2
requests write access to the same file then the request will be denied. The
global object will have a method such as IsPageInUse() which will check
whether the requested page is already in use (I intend to store this
information in a collection) and return true/false accordingly.

What I'd like to know is how much support would I need to include in the
IsPageInUse() method to handle calls from multiple pages? I assume that
multiple calls can be made into the function (as opposed to one at a time
like with STA COM objects) and I will therefore need to add code to ensure
there are no race conditions when checking whether pages are in use, etc.

You're right. You have to handle the case of multiple pages touching your
object at the same time. This can be made easier by being careful to
encapsulate all accesses to your object so that it all goes through methods
and properties of your object. In particular, you must be very careful about
exposing any public fields in your object, as there is no way to control
access to them. Instead, make them public properties and control access to
them in the property setter. Gross oversimplification:

private int _counter;
public int Counter
{
get {return _counter;}
set
{
lock (this)
{
_counter = value;
}
}
}


Note that even this isn't adequate, as it doesn't save you from problems
with "object.Counter++".

If you haven't done multi-threaded programming before, let me offer a bit of
advice: Murphy rules here. Any race condition you haven't prevented from
happening _will_ happen. This is especially true when you haven't tested
under heavy load on a fast, multi-CPU system. And don't assume that because
it hasn't broken visibly, that the code is correct. It just means that you
weren't paying attention when it broke, or that it hasn't broken yet.
 
I will essentially have a collection storing the names of all resources in
use. A method will allow a resource to be flagged as 'in use' which will
effectivly add the name of the resource to the collection. The IsPageInUse()
method (I guess this should be called IsResourceInUse() ) will simply look
to see if the name of the resource is held in the collection.

What I basically need to do is ensure that the collection I'm using to store
the names of resources is locked whenever I need to make changes to it. This
will ensure that if a user requests that 'file2.xml' be locked then should
another user request the same resource the collection will be locked at the
appropriate times thus eliminating the race condition.

I'd also be grateful if you can elaborate more on the Application cache as
opposed to the Application object which is what I'm using now. What
advantages are there?

Thank you,
Wayne.
 
You can use the Synclock() statement in VB.Net, or the lock() statement in
C# to lock any object which you need to. Just pass the object to the
Statement, and put any statements that you want executed when the lock is
established inside the block.

For more detailed information about Application State, see the following SDK
article:\

http://msdn.microsoft.com/library/d.../en-us/cpguide/html/cpconapplicationstate.asp

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
http://www.takempis.com
Big Things are made up of
Lots of Little Things.
 
Back
Top