static constructor is not guaranteed to be finished?

M

Michael Nemtsev

Hello Morgan,

See Jon's explanations there http://www.yoda.arachsys.com/csharp/beforefieldinit.html

MC> In the book *Programming C#* 4th editionby Jesse Liberty, it reads
MC> "Actually, the CLR guarantees to start running the static
MC> constructor before anything else is done with your class. However,
MC> it only guarantees to *start* running the static constructor; it
MC> doesn't actually guarantee to *finish* running it." Page 82, Chap 4
MC> Classes and Objects.
MC>
MC> If it is true, then it is possible that some static fields are not
MC> initialized (by static constructor) when they are used by other
MC> methods. It is terrible.
MC>
MC> Actually, I met some problem about static construtor. I have one
MC> WebService with one static memeber log-writer. The log-writer is
MC> initialized in static constructor with log file name. From time to
MC> time, invocation of webmethod of the service will raise exception.
MC> According to the prints of the exception, it is originated from
MC> static constructor. It says that the log file is already opened by
MC> another process and a Win32 IO Error is generated. That is absurd,
MC> since the log file is only supposed to be used by the webservice.
MC>
MC> This issue cannot be re-produced all the time. If Jesse Liberty is
MC> right, it may explain something. The static construtor is *invoked*
MC> before the WebService class is used. However, the execuation hangs
MC> for some reason. The webservice run to work. some time later, the
MC> static constructor execution resumes and bump into opening the log
MC> file. Oops, conflict!
MC>
MC> Just my guess. Is there anyone else meet similar situation?
MC>
MC> -Morgan
MC>
---
WBR,
Michael Nemtsev :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
M

Morgan Cheng

In the book *Programming C#* 4th editionby Jesse Liberty, it reads
"Actually, the CLR guarantees to start running the static constructor
before anything else is done with your class. However, it only
guarantees to *start* running the static constructor; it doesn't
actually guarantee to *finish* running it." Page 82, Chap 4 Classes and
Objects.

If it is true, then it is possible that some static fields are not
initialized (by static constructor) when they are used by other
methods. It is terrible.

Actually, I met some problem about static construtor. I have one
WebService with one static memeber log-writer. The log-writer is
initialized in static constructor with log file name. From time to
time, invocation of webmethod of the service will raise exception.
According to the prints of the exception, it is originated from static
constructor. It says that the log file is already opened by another
process and a Win32 IO Error is generated. That is absurd, since the
log file is only supposed to be used by the webservice.

This issue cannot be re-produced all the time. If Jesse Liberty is
right, it may explain something. The static construtor is *invoked*
before the WebService class is used. However, the execuation hangs for
some reason. The webservice run to work. some time later, the static
constructor execution resumes and bump into opening the log file. Oops,
conflict!

Just my guess. Is there anyone else meet similar situation?

-Morgan
 
K

Kevin Spencer

Are you closing the log file after writing to it? It doesn't sound like it.
If you're getting an IO exception when you initialize your log writer class,
you are attempting to at least open the file. It almost sounds like your log
writer class is keeping the file opened for its entire lifetime. That is a
*very* bad thing to do. Any unhandled exception will cause the process to
terminate, leaving the file opened. Any other form of abnormal program
termination (such as a power failure) will have the same result.When writing
to files, the rule of thumb is, open, write, and close as quickly as
possible.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A watched clock never boils.
 
C

Chris Taylor

Hi,

From the very basic tests I have performed in the past, it is my experience
that all access to static and instance members across threads are blocked
until the static constructor of a class has completed.

I believe the following extract from clarifies this:

ECMA spec Partition II 10.5.3.1 Type initialization guarantees
3. No methods other than those called directly or indirectly from the type
initializer are able to access members of a type before its initializer
*completes* execution.

For your problem, can you clarify, is the log file opened in the static
constructor and where is it closed?

Hope this helps
 
M

Morgan Cheng

Kevin Spencer 写é“:
Are you closing the log file after writing to it? It doesn't sound like it.
If you're getting an IO exception when you initialize your log writer class,
you are attempting to at least open the file. It almost sounds like your log
writer class is keeping the file opened for its entire lifetime. That is a
*very* bad thing to do. Any unhandled exception will cause the process to
terminate, leaving the file opened. Any other form of abnormal program
termination (such as a power failure) will have the same result.When writing
to files, the rule of thumb is, open, write, and close as quickly as
possible.

Actually, The file is opened in static constructor and not closed
explictly in code. The webservice is supposed to run all the time. So,
I just keep it open , or else it will bring performance isssue to
opne-write-close for every log line. Opened file will be closed
automatically when the process terminates, righit?

Though the IOException can not be re-produced steadily. It happens in
this situation:
I have the webservice run; then I continue to work on the code. After
fixing some bug, I copy related assembly to deployment dir. Then type
"iisreset" in command line. This is supposed to reload new assembly.
Then I invoke the webmethod with utility. It may or may not cause the
IO exception.

Is it possible former w2wp.exe instance is still alive for some time
after "iisreset"?
 
M

Morgan Cheng

Chris Taylor 写é“:
Hi,

From the very basic tests I have performed in the past, it is my experience
that all access to static and instance members across threads are blocked
until the static constructor of a class has completed.

I believe the following extract from clarifies this:

ECMA spec Partition II 10.5.3.1 Type initialization guarantees
3. No methods other than those called directly or indirectly from the type
initializer are able to access members of a type before its initializer
*completes* execution.

For your problem, can you clarify, is the log file opened in the static
constructor and where is it closed?
Since the webservice is invoked frequently. I just let the log file
opened in static constructor and don't close it. I suppose the log file
will be closed when IIS is reset.
 
G

Glenn

Use the event log.


Kevin Spencer ??:
Are you closing the log file after writing to it? It doesn't sound like
it.
If you're getting an IO exception when you initialize your log writer
class,
you are attempting to at least open the file. It almost sounds like your
log
writer class is keeping the file opened for its entire lifetime. That is a
*very* bad thing to do. Any unhandled exception will cause the process to
terminate, leaving the file opened. Any other form of abnormal program
termination (such as a power failure) will have the same result.When
writing
to files, the rule of thumb is, open, write, and close as quickly as
possible.

Actually, The file is opened in static constructor and not closed
explictly in code. The webservice is supposed to run all the time. So,
I just keep it open , or else it will bring performance isssue to
opne-write-close for every log line. Opened file will be closed
automatically when the process terminates, righit?

Though the IOException can not be re-produced steadily. It happens in
this situation:
I have the webservice run; then I continue to work on the code. After
fixing some bug, I copy related assembly to deployment dir. Then type
"iisreset" in command line. This is supposed to reload new assembly.
Then I invoke the webmethod with utility. It may or may not cause the
IO exception.

Is it possible former w2wp.exe instance is still alive for some time
after "iisreset"?
 
W

Willy Denoyette [MVP]

Chris Taylor å?Té"ï¼s
Hi,

From the very basic tests I have performed in the past, it is my
experience
that all access to static and instance members across threads are blocked
until the static constructor of a class has completed.

I believe the following extract from clarifies this:

ECMA spec Partition II 10.5.3.1 Type initialization guarantees
3. No methods other than those called directly or indirectly from the type
initializer are able to access members of a type before its initializer
*completes* execution.

For your problem, can you clarify, is the log file opened in the static
constructor and where is it closed?
Since the webservice is invoked frequently. I just let the log file
opened in static constructor and don't close it. I suppose the log file
will be closed when IIS is reset.



Yep, when issuing an iisreset, the Worker process get's stopped, and all
process owned handles get closed.
You must have another process using the file at the same time, are you sure
no other process is reading from the logfile?.

Willy.
 

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