Shared variables in ASP.NET environment

R

Rob Nicholson

A consequence of the ASP.NET architecture on IIS has just hit home with a
big thud. It's to do with shared variables. Consider a module like this:

Public Module Functions

Public GlobalName As String ' this is ineffect a global
application object

End Module

As there is one aspnet_wp.exe process shared by all users, would all users
access the same GlobalName variable. So if user A runs the application and
sets it to "Fred" and user B sets it to "Bert", then User A sees the new
value?

This this right?

Cheers, Rob.
 
R

Rob Nicholson

As there is one aspnet_wp.exe process shared by all users, would all users
access the same GlobalName variable. So if user A runs the application and
sets it to "Fred" and user B sets it to "Bert", then User A sees the new
value?

Answering my own question but yes, this is what happens. All users access
the same shared variables...

Cheers, Rob.
 
R

Rob Nicholson

Session("GlobalName")="Rob Nicholson"

Hi Ken - I thought about that but the problem was that the variable was
needed deep in a middle tier layer which, I didn't think, new about the
current session. However, I then found:

System.Web.HttpContext.Current.Session("GlobalName")

which means the middle tier can get at the session cache without having to
pass a pointer to it all over the place.

I assume that System.Web.HttpContext.Current is in effect a shared (static)
property that's available process wide and returns the HttpContext object
for the current request being processed which in turn gives the user's own
session state.

Cheers, Rob.
 
K

Kevin Spencer

I clarified this for you a minute ago in another thread. However, I will
repeat my clarification for you:

"Global" and "Shared" are 2 different terms, with 2 different meanings. An
object with global scope (accessibility) may or may not be thread-safe. A
static (Shared) object is certainly NOT thread-safe. Now, this is not the
issue which you addressed specifically, but I am not sure what you meant by
the term "Shared." Any Shared (static) memeber of any class in an
application is, by definition, globally scoped to the application. You don't
even need to create an instance of it, or any class it may reside in. If the
class is included in your application, it is available to the entire
application, and it is globally scoped.

Putting an object into the Application Collection (which, BTW, is not
thread-safe in itself), or into the Application Cache (which is thread-safe
in itself) makes the object global to the application as well. However, in
this case, it is an instance of a class, not a singleton object residing in
the application heap. If you put an object into the Application Collection
or Application Cache, and the object itself is not thread-safe (such as a
Collection, for example), you will run into a whole different set of
problems, as multiple threads may try to access the object at the same time.
A Collection is the easiest example to illustrate. Imagine one thread
attempting to iterate through a Collection while another thread is removing
an item from the Collection.

Now, your remark is in regards to the fact that putting an object into the
Application Collection or the Application Cache makes it globally available,
and thus, when one thread changes its value, it is changed for all threads.
And that is indeed a problem, if you plan to change its value in, for
example, any page used by any user in your app. I just wanted you to
understand the terms, and the possible issues you may encounter.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Neither a follower nor a lender be.
 
K

Kevin Spencer

CORRECTION!

Sorry to make my clarification unclear, but that last paragraph certainly
WAS unclear (and incorrect). I said that you were referring to using the
Application to store objects, when, in fact, you were referring to a Module,
which, by definition, contains all Shared (static) members. And, of course,
you wouldn't be storing Module members in the Application!

Apologies,

Kevin Spencer
Microsoft MVP
..Net Developer
Neither a follower nor a lender be.
 
R

Rob Nicholson

the term "Shared." Any Shared (static) memeber of any class in an
application is, by definition, globally scoped to the application. You
don't

Actually, this is in a module and I assume that modules are in effect
shared:

Public Module Functions

Public GlobalName As String

End Module

Functions.GlobalName appears to be accessible from everywhere.
understand the terms, and the possible issues you may encounter.

We were using something akin to above but actually storing a reference to
our own application object so actually we had:

Public Module Functions

Public GlobalApp As OurApp

End Module

This was a no-no as all users (sessions) started sharing the same OurApp
which could have started the thread-safe problems you describe, e.g. one
user could clear OurApp.BigCollection whilst another user was using it.

I've made a simple change to our application environment to store OurApp in
the session cache instead which, AFAIK, will be fine as each other now gets
their own instance of OurApp.

Realising that all users are running in the same process with the same
instance of the DLLs et all plus shared memory and heap was a important
realisation for me. The penny dropped.

I've done a fair amount of multi-thread stuff in the past but not thought
about it too much in the ASP.NET environment.

Cheers, Rob.
 
K

Kevin Spencer

Hi Rob,

Yes, see my self-correction which I posted almost immediately after the post
you reponded to. I realized that you were not talking about using the
Application to store data, but a Module. It is true that every member of a
Module is Shared (static), a singleton that is available throughout the
application.

Modules are a special kind of class, another accomodation of Microsoft for
VB6 developers. However, it is not good practice to use Modules at all, as
they present no accessibility control whatsoever. In addition, they often
confuse VB developers who are accustomed to using them in executable
applications, and do not understand the consequences of using them is a web
application, particularly one that is multi-threaded. Instead, use classes.
You can create classes which have both Shared (static) members and members
with other (instance-type) accessibility as well, which gives you full
control over the members in the class.

Shared (static) objects present a number of difficulties in a multi-threaded
environment. That is not to say that they are not useful. Shared methods,
for example, are often quite useful, as they reduce the stack size, and
therefore memory usage. Shared fields and properties are problematic, but
useful in certain situations (particularly when the classes which use them
do not change them). One excellent way of making sure that client classes do
not change them is to create a private Shared field, and expose it via a
public Shared read-only property. Example:

Public Class Foo

Private Shared _Bar As String
Public Shared ReadOnly Property Bar() As String
Get
Return _Bar
End Get
End Property

' Public Constructor
Public Shared Sub New()

End Sub

' Shared Constructor
Shared Sub New()
_Bar = "Foo Bar"
End Sub

End Class

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Neither a follower nor a lender be.
 
C

Cor Ligthert [MVP]

Kevin,

I can be mistaken however reading your messages, are you in my opinion
missing the point which is that a shared variable in an ASPNET persistent
however it is part of the application (as it is everywhere), however in
ASPNET belongs an application to all clients.

Persistent to a client action (postback) in ASPNET are
A viewstate item (belongs to the page)
A session item (belongs as IIS part to the client)
A shared variable (belongs to the application)
A cache item (is used by the total application)

A global item in ASNET is not persistent in the way as windowsforms where it
is almost forever persitent.

I hope this helps,

Cor
 
R

Rob Nicholson

VB6 developers. However, it is not good practice to use Modules at all, as
they present no accessibility control whatsoever. In addition, they often

We don't use them much at all - our Functions module has just three system
wide modules. And in fact, they could probably be included in the basic App
class anyway. I saw the OOPs light many years ago :)

Cheers, Rob.
 
S

Scott Allen

A global item in ASNET is not persistent in the way as windowsforms where it
is almost forever persitent.

How do you define a global item?

A field declared as static in C#, or shared in VB.NET, behaves exactly
the same in ASP.NET and forms based applications. The field will be
around for the duration of the application domain.
 
S

Steven Cheng[MSFT]

Hi Rob,

The static(in C#) or shared (in VB.NET) class members are global in the
scope of a certain AppDomain. So different appdomain will maintain their
own values of these variables. For ASP.NET applications, each separate
application is hosted in a separeate appDomain so they'll have their own
copy of the Variable values.

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
--------------------
| From: "Rob Nicholson" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: Re: Shared variables in ASP.NET environment
| Date: Thu, 15 Sep 2005 19:02:23 +0100
| Lines: 10
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.3790.181
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.181
| Message-ID: <[email protected]>
| Newsgroups:
microsoft.public.dotnet.framework.aspnet,microsoft.public.dotnet.languages.v
b
| NNTP-Posting-Host: host217-45-2-106.in-addr.btopenworld.com 217.45.2.106
| Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
| Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.languages.vb:105909
microsoft.public.dotnet.framework.aspnet:124898
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| > VB6 developers. However, it is not good practice to use Modules at all,
as
| > they present no accessibility control whatsoever. In addition, they
often
|
| We don't use them much at all - our Functions module has just three system
| wide modules. And in fact, they could probably be included in the basic
App
| class anyway. I saw the OOPs light many years ago :)
|
| Cheers, Rob.
|
|
|
 
K

Kevin Spencer

I can be mistaken however reading your messages, are you in my opinion
missing the point which is that a shared variable in an ASPNET persistent
however it is part of the application (as it is everywhere), however in
ASPNET belongs an application to all clients.

Missing WHAT point? What exactly is THE point?

Persistence and Scope are 2 rntirely different topics.

The scope of my discussion was confined to the scope and behavior of various
types of global objects. Of course, I did mention that Shared (static)
objects reside in the application heap, which implies, of course, that they
are permanently memory-resident for the lifetime of the application.
A global item in ASNET is not persistent in the way as windowsforms where
it is almost forever persitent.

Your use of the term "global" is ambiguous. "Global" scope refers to any of
several different types of scope. An object can be scoped globally to a
page, to a Session, to an application, to a machine, to a domain, to an
enterprise, or to the entire Internet. Assuming that we are confining our
discussion to an ASP.Net web application, that still leaves Page scope,
Session scope, and Application scope.

Items stored in the Application Collection are persistent throughout the
lifetime of the Application , just like Windows Forms. Shared (static) items
are also persistent throughout the lifetime of the Application , just like
Windows Forms. Instantiated items stored in the Application Cache can be
persistent for as short or as long a time as the developer requires,
including the lifetime of the Application, just like Windows Forms.
Instantiated items stored in Session are persistent throughout the lifetime
of the Session.

None of these facts contradicts my (and Microsoft's) recommendations
regarding the use of Modules or Shared (static) objects. Of course, I can
only guess that this is what you are taking issue with here.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Neither a follower nor a lender be.
 
C

Cor Ligthert [MVP]

Kevin,

You are replying your own messages. Read mine, I don't write that you are
wrong in your answers. I only write that you are in my opinion missing the
most important factor (point). An Aspnet application (the dll) belongs to
all clients, a windowsform (UI) application (the exe) to one client.

Cor
 
K

Kevin Spencer

I'm not missing anything, Cor. Not missing any points, not misunderstanding
anything.

If you want to believe what you're saying, you are welcome to. I might point
out, for example, though, that a DLL is not an application. It is a file
containing code that is loaded into the application memory when the
application starts. And that there are quite a few more than one DLL loaded
when the application starts, most of them in the Global Assembly Cache, and
often more than one in the Application bin folder. And that clients, in the
case of ASP.Net, are HTTP client applications residing outside of the
Application domain of an ASP.Net application, and therefore, have no access
at all to the ASP.Net application.

Finally, this is not helpful to the OP, and it's just plain irritating to
me, so how about quitting?

--

Kevin Spencer
Microsoft MVP
..Net Developer
Neither a follower nor a lender be.
 
Joined
Jun 28, 2007
Messages
2
Reaction score
0
Converting Public Shared to Session

I have a bit of a problem.

I have a lot of public variables that are accessed by several pages.
I also have data structures and some are defined as an array

Problem I see is that 2 or more users are sharing data that is user 1 places an order and user 2 has the same order data.

These common variables are defined in a separate class


such as:

Public Class appvars

Structure OrderDetail
Public RowActive As Boolean
Public PartNumber As String
Public QtyReqd As Integer
Public Price As Decimal
Public Description As String
Public Sumtotal As Decimal
Public FgLoc As String
Public FgBal As Long
Public WhseLoc As String
Public WhseBal As Long
Public Reserved As Boolean ' if true then part has a resv entry
Public ResNumber As String
Public ResPos As String ' reservation location?
Public ResUser As String
Public ReqDate As String
End Structure


Public Shared Order(-1) As OrderDetail

and so on.

How can I make these application level variables into session level.
A user could even have 2 or more active web pages open and running the same application so I need to isolate the data at the user and session level.

I looked at session("xx") = xx style code but it doesn't appear to support more complex data types.

Is there any way I can add a simple line of code to isolate the user data from other users and web pages?

any ideas? :hmm2:

thx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top