views:

53

answers:

3

Suppose I have a.aspx and b.aspx both with a function f.

I also have an object instance, o, that is held in Session.

Each client has ajax scripts that call a.f and b.f asynchronously.

a.f calls o.ReadData

b.f calls o.ReadData

Object, o, maintains one open file handle, from instatiation, until it is disposed.

Are there any concurrency issues with accessing the file in o? Why or why not?

A: 

If the file is read-only, you won't have any issue.

A million non-exclusive readers on one file don't cause issues. If there is a possibility of one (or more) writers will you have an issue and need to lock. If your file open specifically grabs an exclusive file handle, then other openers will fail. Otherwise, you're fine.

This SO question deals with the general issue of concern: http://stackoverflow.com/questions/823479/multiple-threads-reading-from-the-same-file

As that link describes, it is important that your file handle is thread-specific local memory, rather than shared. If ReadData simply opens the file itself, you're fine. However, if some static function uses a global var to hold an always-open file handle, you could get into trouble. So be sure to open it in the function being threaded with a local/stack variable.

Scott Stafford
@Scott Stafford - Not to be obtuse, but why would that work? What is causing the requests to be serialized?
User09874845
I think that is wrong. Let's say the file starts at position 0. If A reads before B, B will be starting at another location in the file than expect. Even if you Seek before Read, the other thread might have been reading the file between those two calls.
driis
@Userxxx: Nothing serializes them, but they work fine in parallel. @driis: The file handle exists in thread memory, not globally used... see EDIT.
Scott Stafford
@Scott, not if only one file handle is used. The accepted answer on your link explicitly talks about having multiple handles to the same file; but that is not the case here. As stated in the question: "Object, o, maintains one open file handle, from instatiation, until it is disposed"
driis
@driis: That's true, and it could be coded wrongly. But I believe the most likely coding would have the file open be inside the thread context and not in shared mem, ie his ReadData just opens the file. I will edit to clarify.
Scott Stafford
+1  A: 

a.aspx and b.aspx are separate pages; so they can be requested in parallel, and are likely to be so by the browser; if both are used by your AJAX script. The two page requests will probably run on two separate threads; if they get requested at roughly the same time.

These objects share a single object; which has an open file. This is a concurrency issue - a and b can access the object at the same time. So reads by b might not be from the location you expect; or worse, you could write to a wrong part of the file, if you are writing.

Under all circumstances; I would not like putting an open file in a Session object. How do you know when to close the file ? You might have a resource leak there.

driis
a.aspx can also run in parallel with a.aspx. Being separate pages is not required for simultaneous use.
Jon Hanna
@Jon, good point.
driis
Where did the Session object come from? He didn't mention one... He should def open and close it inside the ReadData method though..
Scott Stafford
A: 

The answer from what you've said so far is "probably".

Note, that you don't even need this situation of two different ASPX files, two requests to the same ASPX file would have the same issue, as each ASPX file can handle multiple simultaneous requests.

The big question is how does the object at o deal with it's file. If it's being used in a re-entrant manner, then that's fine. This is to say, if at any point you could have another thread call the method and because no state in the object is ever changed (only local variables get changed, no instance or static members) then you are fine.

If not, then you will need to lock on the methods in question. However, locking introduces a bottleneck in the flow. Even if there's never a deadlock, requests will queue up at this point, and if the method can't release the lock faster than new requests come in, the delay caused by that queue will get bigger and bigger until it becomes a serious problem.

If by "holds a file handle", you mean it has a File object, and it calls File.OpenRead each time it is used, before disposing of the stream returned in the same call, then that's fine. If however you mean that you have the stream returned by File.OpenRead and you Seek before each read, then you've got a concurrency issue.

While for a single threaded console application it may be more efficient to open a stream with OpenRead and then Seek if you need to look at the start of the file again, with a multithreaded application (and all ASP.NET is inherently multi-threaded even if you never explicitly create a thread) it is much, much more efficient to call OpenRead each time you need to.

Jon Hanna