Microsoft Data Access Block and static methods

  • Thread starter Thread starter Clint
  • Start date Start date
C

Clint

Hey all -

Excuse the cross-post ... I'm not sure what the appropriate newsgroup
would be for this question.

I have a question that I'm not quite sure how to ask. For all I know, I
have the verbaige completely wrong, but here goes nothing ...

I'm currently using the MS Data Access Block for a desktop application
I'm writing. Recently, I had to add a call to a web service, which in
itself calls a mssql database. I had figured that I would just use the
MS DAL as I was in the client app, but then found myself confused about
something: How can a web service, with multiple people connecting to it
at any given time, use a static method to get it's data?

In past experiences with ASP.NET applications, if I had a static
variable declared and set by one User A, User B browsing to that page
would see the new value set by A. Isn't the same possible for database
calls? If User A calls my web service at the same time User B calls it,
isn't it possible that B might get A's result, or vice versa?

I think it might come down to my idea of how static variables work: I
look at the MSDN docs and see that SqlCommand has the following:

"Any public static (Shared in Visual Basic) members of this type are
safe for multithreaded operations. Any instance members are not
guaranteed to be thread safe."

I would figure it to be completely opposite - that if multiple threads
are hitting a static member, it'd be possible those results could get
returned to the wrong user, whereas in an instance member, each method
being called is a separate logical piece, so there's no results being
misguided.

Can anyone help me out with this? I'm not new to the programming world,
but for some reason I'm finding this really confusing.
Thanks in advance!
Clint
 
Most of the methods in the DAB are stateless. The methods use only the
incoming parameters and local variables. The problem you faced in
ASP.NET development was using a static variable to store information.
Think of it as having only one "slot" available to store a piece of
data so every user sees the data from the single slot.

There are a few static fields in the DAB (for SqlParameter caching, if
I remember), but these fields are guarded with locks to prevent
concurrent threads from screwing it up, and the data (information
about what SqlParameters are required by a stored procedure) is global
for every user.

Making any sense?

As for the MSDN docs, they are saying that the static member methods
are written to be thread safe, so they have to use locks where
appropriate. MS assumes the framework is going to be used in a
multithreaded environment and couldn't let static methods not be
thread safe.

That being said, instance members are not safe because a single
instance of an object is typically not going to be used by multiple
threads. In ASP.NET for instance, you typically create an instance of
a class for each user request - a TextBox control will never see
multiple threads. Since locks add some performance overhead (and a lot
of development and testing overhead), the decision makes a great deal
of sense, even if it looks counterintuitive at first.
 
Clint,

I had the very same question a few days back - and I wrote up a quick neato
sample. Basically I had a class with a static method, doing a
console.writeline of the thread id it was in. I then fired off 2 threads and
called the same class repeatedly and to my surprise the static method
returned me ... different thread ids. Very enthused, I wrote up another
sample in which I put a 5 minute sleep in the static - and well if the very
same instance was being shared either thread would have to wait 5 minutes
before being able to use the ONE COMMON instance - ... and to my suspection
... it didn't !!!! Which led me to believe that ---

Even static methods are created on each thread - but within the thread there
is one and only one instance. Every thread gets it's own private copy of a
static method.

So there - static methods are threadsafe which is why the famous line -- "
"Any public static (Shared in Visual Basic) members of this type are
safe for multithreaded operations. Any instance members are not
guaranteed to be thread safe."

"

What do they mean by instance members? Well what that means is, if you have
module level static methods, then two threads will actually share the same
value, and you need mutexes or some other method to lock access to those -
or you might get unexpected values in them. But methods - are cool !! module
level variables are not cool.

So go ahead use the DAB without worrying about statics :)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
http://blogs.apress.com/authors.php?author=Sahil Malik
 
Thanks Sahil!

If you don't mind, I just have a few more questions on top of those
already answered, just to make sure I understand whats actually going
on.
Even static methods are created on each thread - but within the thread there
is one and only one instance. Every thread gets it's own private copy of a
static method.

Let's pretend for a second that I have a client app that uses MDI forms
- call one MDI Child Profile, the other Search.
That said, I have a utility class,
class Foo
{
public static DataSet StaticDatabaseQueryMethod()
{
// do something that returns a DataSet
}
}

In MDIChild Profile, a timer spawns a thread that calls
Foo.StaticDatabaseQueryMethod() that will return the user's profile. At
the same time, the user is really looking at the Search MDI Child form,
and search that spawns it's own thread and performs the search - again
- using Foo.StaticDatabaseQueryMethod().

If I'm understanding right, I have three threads running (Main GUI,
Profile query, and Search query). Because these are on separate
threads, the two queries can both access the static Foo member, and
will not have any issues with data being returned to the wrong form
(ie, Profile's return set goes to Search, and vice versa)?
What do they mean by instance members? Well what that means is, if you have
module level static methods, then two threads will actually share the same
value, and you need mutexes or some other method to lock access to those -
or you might get unexpected values in them. But methods - are cool !! module
level variables are not cool.

In other words, using static for methods is ok, but static for fields
within a class isn't?

Another example, sorry :)
class Foo
{
private static string fooField; // this is a bad idea, and will
require lock(...) when accessing
private static string fooMethod() {} // this is OK to do, and will
return correct values so long as it's called by separate threads
}

Thanks again!
Clint
 
Thanks, Scott!

The first part of your post did in fact clear up the big hangup I had
w/the MS DAL. I'd just like to try to clarify a few points, though ...
sorry for the constant questions, I just want to make sure I have this
fully understood before I make a big mistake that would cause quite a
lot of problems if data gets mixed up :)

----------
MS assumes the framework is going to be used in a multithreaded
environment and couldn't let static methods not be thread safe.
----------

So I don't have to worry about adding my own lock(...) commands when
referencing MS-written static methods, but if I'm writing my own static
methods that reference static fields in a class, I should use
lock(...)?
ie,

class Foo
{
private static string testValue;

public static void AdjustTestValue()
{
lock (this) // or lock(typeof(Foo))?
{
testValue = "something";
}
}
}

----------
That being said, instance members are not safe because a single
instance of an object is typically not going to be used by multiple
threads. In ASP.NET for instance, you typically create an instance of a
class for each user request - a TextBox control will never see multiple
threads. Since locks add some performance overhead (and a lot of
development and testing overhead), the decision makes a great deal of
sense, even if it looks counterintuitive at first.
----------

I'm having trouble understanding this ... do you mean that in an
ASP.NET (and, for my purpose, Web Services), I should be instantiating
classes instead of using statics, or that it's ok to use statics in
that each request is processed on it's own thread, so long as I don't
actually STORE a value in a static field(ex, inside the static method,
I perform a SQL query only, not storing the result of that query to a
static field)?

Thanks again!
Clint
 
Hi Clint:

So I don't have to worry about adding my own lock(...) commands when
referencing MS-written static methods, but if I'm writing my own static
methods that reference static fields in a class, I should use
lock(...)?
ie,

It's always good to check the docs, but generally the MS static
methods are thread safe.
class Foo
{
private static string testValue;

public static void AdjustTestValue()
{
lock (this) // or lock(typeof(Foo))?
{
testValue = "something";
}
}
}

Yes, a lock would be needed. Remember you can't use "this" in a static
method. Jon has a good article on picking what to lock on:
http://www.yoda.arachsys.com/csharp/multithreading.html#lock.choice
----------
That being said, instance members are not safe because a single
instance of an object is typically not going to be used by multiple
threads. In ASP.NET for instance, you typically create an instance of a
class for each user request - a TextBox control will never see multiple
threads. Since locks add some performance overhead (and a lot of
development and testing overhead), the decision makes a great deal of
sense, even if it looks counterintuitive at first.
----------

I'm having trouble understanding this ... do you mean that in an
ASP.NET (and, for my purpose, Web Services), I should be instantiating
classes instead of using statics, or that it's ok to use statics in
that each request is processed on it's own thread, so long as I don't
actually STORE a value in a static field(ex, inside the static method,
I perform a SQL query only, not storing the result of that query to a
static field)?

It is OK to use static methods in a multithreaded app, the place to be
very careful is when using static fields.
 
"If User A calls my web service at the same time User B calls it, isn't
it possible that B might get A's result, or vice versa?"

You could set EnableSessionState to true in the WebMethod atribute so
that the webservice could maintain the state for the client until the
method completes its execution. Anyway, it is not just session state
that is important when using a webservice as a Data Access Layer, it is
also the TransactionContext. More on transactions in Web Services upon
your reply.


"Any public static (Shared in Visual Basic) members of this type are afe
for multithreaded operations. Any instance members are not guaranteed to
be thread safe."

"I would figure it to be completely opposite - that if multiple threads
are hitting a static member, it'd be possible those results could get
returned to the wrong user, whereas in an instance member, each method
being called is a separate logical piece, so there's no results being
misguided."

It is not the opposite, though, you would need to lock the application
state, if you are talking about the ASP.Net environment (and if you are
not, I am), before writing or accessing a static member.


with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
Back
Top