Home All Groups Group Topic Archive Search About

Microsoft Data Access Block and static methods

Author
9 Dec 2004 9:48 PM
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

Author
9 Dec 2004 10:40 PM
Scott Allen
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.

Show quote
On 9 Dec 2004 13:48:02 -0800, "Clint" <cjmuel***@gmail.com> wrote:

>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
Author
10 Dec 2004 6:37 AM
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
Author
10 Dec 2004 2:43 PM
Scott Allen
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

Show quote
>
>----------
>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.

Author
10 Dec 2004 5:58 PM
Clint
Excellent - that clears up a lot.

Thanks again!
Author
9 Dec 2004 10:46 PM
Sahil Malik
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




Show quote
"Clint" <cjmuel***@gmail.com> wrote in message
news:1102628882.166011.55670@z14g2000cwz.googlegroups.com...
> 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
>
Author
10 Dec 2004 6:20 AM
Clint
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
Author
10 Dec 2004 9:49 AM
Sahil Malik
Clint .. answer to Q#1 - Yes, as long as the implementation of
StaticDatabaseQueryMethod doesn't rely on instance members that are static.

Answer to Q#2 - Yes you need a locking mechanism to access that variable to
ensure data sanctity.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik




Show quote
"Clint" <cjmuel***@gmail.com> wrote in message
news:1102659626.502962.53650@f14g2000cwb.googlegroups.com...
> 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
>
Author
10 Dec 2004 7:27 PM
Clint
Makes perfect sense - thanks again, Sahil!

AddThis Social Bookmark Button