static constructor and multithreading

M

Marek

Hi,

I am analyzing Duwamish7 source code boundled with Visual Studio .NET 2003.
Could anoybody explain why the Monitor.Enter and Monitor.Exit block is used
inside a static constructor? The code can be found in Project
SystemFramework within module ApplicationLog.cs. Here comes the sample.

namespace Duwamish7.SystemFramework {

(some code...)

public class ApplicationLog {
(some code..)
static ApplicationLog() {
Type myType = typeof(ApplicationLog);
try {
if (!Monitor.TryEnter(myType)) {
Monitor.Enter(myType);
return;
}
(some code..)
}
finally {
Monitor.Exit(myType);
}

} // static constructor

} // class ApplicationLog

(some code..)

} //namespace Duwamish7.SystemFramework

Mark
 
N

Nicholas Paldino [.NET/C# MVP]

Marek,

It is possible that there are other areas of the code that are using the
type of ApplicationLog as the object on which to lock a section of code.
Getting the Type of a class doesn't cause static constructor code to fire
(using typeof).

Hope this helps.
 
C

cody

It is possible that there are other areas of the code that are using
the
type of ApplicationLog as the object on which to lock a section of code.
Getting the Type of a class doesn't cause static constructor code to fire
(using typeof).


Does that mean that a static ctor could be called more than once?
 
N

Nicholas Paldino [.NET/C# MVP]

cody,

No, it does not. However, just because code locks on that particular
type, doesn't mean that code in other sections of the application can't lock
on that same type.
 
C

cody

No, it does not. However, just because code locks on that particular
type, doesn't mean that code in other sections of the application can't lock
on that same type.

I'd lie if I'd say I understood this. Iam no threading expert could you
please explain this to me?
 
N

Nicholas Paldino [.NET/C# MVP]

cody,

When you use the lock keyword, you need an object reference to use as a
lock. In the static constructor, it is locking on the type that the static
constructor is for (since it is an instance of type Type). Now, this
doesn't mean that some OTHER code can't lock on the same instance of Type.
It doesn't always have to lock around the SAME code.
 
M

Marek

Hi Nicolas,

Thank you for your explanation but there's still something that I don't
understand.
Please listen to the following and point where I make a mistake.

1. Static constructor (SC) is garanteed to be executed not more then once
(isn't it?).
2. If a class contains only static methods (which is the case) SC is
executed (implicite) BEFORE the first call to a static method.
3. That means that SC code cannot interfere (i.e. be executed
simultaneously) with any other static method code.
4. As a result, there's no need to protect execution of SC against
multithreading safety.

Helper question. Is it possible the a static method (let's say in another
thread) starts its execution before the execution of static constructor
ends?

Thanks
Marek

Nicholas Paldino said:
cody,

No, it does not. However, just because code locks on that particular
type, doesn't mean that code in other sections of the application can't lock
on that same type.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

cody said:
using
the


Does that mean that a static ctor could be called more than once?

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
 
J

Jon Skeet [C# MVP]

Marek said:
Thank you for your explanation but there's still something that I don't
understand.
Please listen to the following and point where I make a mistake.

1. Static constructor (SC) is garanteed to be executed not more then once
(isn't it?).

Yes, so long as it's not called directly by reflection.
2. If a class contains only static methods (which is the case) SC is
executed (implicite) BEFORE the first call to a static method.
Yes.

3. That means that SC code cannot interfere (i.e. be executed
simultaneously) with any other static method code.
Yes.

4. As a result, there's no need to protect execution of SC against
multithreading safety.

Well, it depends on what that static constructor does. It may call
other methods which aren't thread-safe, and need to acquire the same
locks as other callers of those methods acquire.
Helper question. Is it possible the a static method (let's say in another
thread) starts its execution before the execution of static constructor
ends?

Not usually - there are times where you'd get deadlock otherwise, and
times where it's the thread which is executing the static initializer
which is also executing the static method. For instance:

static Foo()
{
DoSomething();
}

static void DoSomething()
{
}

Clearly DoSomething is called before the static method has completed
here, by definition.
 
M

Marek

Hi Jon:

I was not precise enough in the question 4. Of course, other resources may
have to be protected against concurrent access. I meant that locking on the
type class instance inside the static constructor does not make any sense.
Is that correct?

As far as I have understood your answer to the helper question, CLR provides
some kind of protection against letting other static methods get started
before the static constructor ends its execution. Is that what you said?

Marek
 
J

Jon Skeet [C# MVP]

Marek said:
I was not precise enough in the question 4. Of course, other resources may
have to be protected against concurrent access. I meant that locking on the
type class instance inside the static constructor does not make any sense.
Is that correct?

No - because as Nicholas said, other classes may be using the type for
locking as well. The things that the static constructor does may need
to execute separately from anything else which would lock on the type.
As far as I have understood your answer to the helper question, CLR provides
some kind of protection against letting other static methods get started
before the static constructor ends its execution. Is that what you said?

Yes, with some conditions. See section 9.5.3 of partition 1 of the ECMA
spec for more details.
 
M

Marek

Thank you Jon. It's more than clear now.
Marek

Jon Skeet said:
No - because as Nicholas said, other classes may be using the type for
locking as well. The things that the static constructor does may need
to execute separately from anything else which would lock on the type.


Yes, with some conditions. See section 9.5.3 of partition 1 of the ECMA
spec for more details.
 

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

Top