ASP.NET file system operations...should file writes use locks?

M

moo

A fascinating discussion on "Threads in asp.net" (http://
groups.google.com/group/microsoft.public.dotnet.languages.csharp/
browse_thread/thread/f5a8fc4eed6d2d8f/5bee26eb7f1274d6?
lnk=gst&q=threads+in+asp.net#5bee26eb7f1274d6) from moons ago says
that the ASP.NET worker process handles all sites concurrently in the
worker process thread pool...I'm curious how that statement stands up
to newer versions of the framework (I'm targeting 3.0).

I have a form that I want a user to fill out with information, then I
want to generate a report to e-mail to an overseer with the form's
contents. I'm trying to be cute and dynamic about it, and have created
a snippet as follows:

protected void btnSubmit_OnClick(Object sender, EventArgs e)
{
List<string> formContents = new List<String>();
foreach (AccordionPane pane in IntakeAccordion.Panes)
{
foreach (Control conty in pane.ContentContainer.Controls)
{
if (conty.Visible) //assume irrelevant controls aren't
visible...
{
if (conty.HasControls())
formContents.Add(getChildContents(conty));
//Need to go back and change plain text HTML
prompts into Labels...there was a method behind my madness in the
first place!
formContents.Add(getControlValue(conty));
}
}
}
string fileName = System.IO.Directory.GetCurrentDirectory() +
txtFirstName.Text + "_" + txtLastName.Text +"_IntakeReport.doc";
//I may not need to do this, but I think on the web if I have
two people entering the same client name at the same time and they
happen to click this button, I might create a race condition...this is
probably the best approach
lock(this)
{
//This is why C# is ****ing awesome! Take a dynamic list
of created contents, and in two lines make it an array and use a
library function to achieve complex functionality...thank you for
making my life not suck!
System.IO.File.WriteAllLines(fileName,
formContents.ToArray());
}

EmailOverseer(fileName);
}

My question is: do I need that lock? My initial feeling is that since
I'm creating a file name based upon the names entered in the fields (I
should probably sanitize those inputs..aside from regexs looking for A-
Z, any other checking ideas I should do would be welcome), I may
someday have the odd condition where two users are entering
information for the same person and happen to click the button at the
same time, possibly creating a race condition. Is that accurate?
 
J

Jon Skeet [C# MVP]

My question is: do I need that lock?

I seriously doubt that it'll be doing anything useful at the moment.
You're locking on "this", but a new page instance is created for each
request, I believe.
My initial feeling is that since
I'm creating a file name based upon the names entered in the fields (I
should probably sanitize those inputs..aside from regexs looking for A-
Z, any other checking ideas I should do would be welcome), I may
someday have the odd condition where two users are entering
information for the same person and happen to click the button at the
same time, possibly creating a race condition. Is that accurate?

I would suggest creating a file with a temporary filename (e.g.
creating a new GUID and using that) and then modify EmailOverseer so
it can send the attachment *as if* the file had the desired filename.

In fact, does EmailOverseer really need the file to be on disk in the
first place? Any reason you can't use memory directly? (e.g.
MemoryStream)

Jon
 
M

moo

Good point...I was thinking I needed to instantiate a file object and
then lock on that object, but I tried to get lazy and use the static
method (because a couple of bytes on the stack are all so
important...*smacks self*) without thinking it through.

Thanks for your suggestion, I can probably do that...this is more of a
proof in concept solution, and the dumb and lazy approach is to
automatically generate the report in a file and then attach that file
to the e-mail...if I want to get fancy I may want to generate an XML
so I can e-mail it out in HTML format and have a source for back end
queries later, but that's another topic...

The main gist of the question was, what are some standard patterns/
best known methods for handling file system interactions in ASP.NET?
Do we treat them similarly to multi-threaded console apps, or are
there other considerations we need to account for/simplify things? Any
specific resources would be welcome.
 
J

Jon Skeet [C# MVP]

moo said:
Good point...I was thinking I needed to instantiate a file object and
then lock on that object, but I tried to get lazy and use the static
method (because a couple of bytes on the stack are all so
important...*smacks self*) without thinking it through.

Thanks for your suggestion, I can probably do that...this is more of a
proof in concept solution, and the dumb and lazy approach is to
automatically generate the report in a file and then attach that file
to the e-mail...if I want to get fancy I may want to generate an XML
so I can e-mail it out in HTML format and have a source for back end
queries later, but that's another topic...

The main gist of the question was, what are some standard patterns/
best known methods for handling file system interactions in ASP.NET?
Do we treat them similarly to multi-threaded console apps, or are
there other considerations we need to account for/simplify things? Any
specific resources would be welcome.

I haven't heard of any particular rules - I'd just say:

1) Writes should usually be to different files anyway, apart from for
logging (lock in that case)
2) Concurrent reads should be fine (open shared) so long as you don't
have anything else writing
3) Try to avoid it in the first place if possible
 

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