Click to See Complete Forum and Search --> : Two requests to same aspx page at the same time


bacchus99
December 24th, 2008, 11:35 AM
I have a website project in VS2008 using C# as code behind. This site has one page default.aspx that searches a database based on parameters sent via the URL that looks like this:

Default.aspx?image_side=front&aba_number=123456789&check_number=&amount=7500&account_number=12345&date_posted=04/05/2007&app_code=D&deb_cred=D&reference=020101400&reference_type=2

The website just sits on a webserver on an intranet where other computers on the same network make request to it. The page looks in the database to find the record and if found builds a path to an image that is on the webserver. If everything is good it returns just contenttype="image\jpeg" and then the image found by doing a Image.Save(Response.OutputStream, ImageFormat.Jpeg);

The problem is when a request comes in for the front and back of the image in two seperate but almost simultaneous requests. In the debugger the page_load gets hit for both request almost at the same time. The debugger starts bouncing around lines of code as you step thru it because it is running both requests. Of course this screws up the way the code executes as well as generates errors. I'm using member variables to the _Default class that keep getting overwritten by the second request. Hope this makes sense. I have searched the web high and low and not sure what else to look for. I'm obviously not much of a web developer as I normally just do applications. I need the return of the page to be an image and not xml or html. Any ideas?

marceln
December 24th, 2008, 11:43 AM
This shouldn't happen. For two different requests (from two users, therefore two different sessions) there should be two instances of the page controller.

Do you have any static members/classes or use session variables that are shared by the two concurrent requests?

bacchus99
December 24th, 2008, 12:00 PM
The two different requests come from the same PC/user. We are displaying checks and they make one request for the front of the check and one for the back at almost the same time so I guess that is the same session? Not using any statics but I am using plain member variables. I am not using any session variables either.

marceln
December 24th, 2008, 12:09 PM
The two different requests come from the same PC/user. We are displaying checks and they make one request for the front of the check and one for the back at almost the same time so I guess that is the same session? Not using any statics but I am using plain member variables. I am not using any session variables either.

But are you sure something wrong is actually happening? The results you notice while debugging could be due to context switching. The web server creates two execution flows to handle the two requests.

Could you put a breakpoint in Page_Load and open Debug/Windows/Threads and inspect the values of the member variables and/or request parameters for both request contexts? You could be mistaking, since debugging a multithreaded application like that could be misleading. Or I could be mistaking and a problem indeed exists :).

bacchus99
December 24th, 2008, 12:53 PM
The front and back images are in the same file on the disk(multipage tiffs). Maybe the image file is locked from the front request when the back request tries to access it?

marceln
December 24th, 2008, 12:59 PM
The front and back images are in the same file on the disk(multipage tiffs). Maybe the image file is locked from the front request when the back request tries to access it?
oh, of course. that's your problem.
can't you span the tiff in multiple images? this or there may be possible to open the file in shared mode.
how do you open the file? can you paste here a code snippet?

bacchus99
December 24th, 2008, 01:51 PM
Stream s = File.Open(pathToImage, FileMode.Open);
System.Drawing.Image myimage = System.Drawing.Image.FromStream(s);
myimage.SelectActiveFrame(FrameDimension.Page, frameFront);
Response.ContentType = "image/jpeg";
myimage.Save(Response.OutputStream, ImageFormat.Jpeg);
s.Close();

TheCPUWizard
December 24th, 2008, 01:54 PM
Add...

private static object s_Sync = new Object();

//then in your code...
lock(m_Sync)
{
// Access the file only inside here
}

marceln
December 24th, 2008, 02:06 PM
wizard, although that would be a possible solution in a desktop multithreaded application, this is not the case for a web application. Consider the case when you have hundreds or thousands of clients making almost concurrent requests...

bacchus99, you can use:

Stream s = File.Open(pathToImage, FileMode.Open, FileAccess.Read, FileShare.Read);

The last parameter means that there are allowed subsequent read operations, while the file is open.

bacchus99
December 24th, 2008, 02:11 PM
Yeah I just figured that out. Thanks for all the help....never realized the file.open method was overloaded for file sharing!

bacchus99
December 24th, 2008, 02:16 PM
Well now it sometimes displays the back image for the front and vice versus....it is like there is a race condition on the script from the two requests?!?

TheCPUWizard
December 24th, 2008, 02:26 PM
wizard, although that would be a possible solution in a desktop multithreaded application, this is not the case for a web application. Consider the case when you have hundreds or thousands of clients making almost concurrent requests...

Except that is NOT the (Apparant) case.

The website just sits on a webserver on an intranet where other computers on the same network make request to it.


Perhaps even more important is what happens IF you do scale up to many users, and have requrests which directly access the hard drive (NOT talking about situations with advanced SAN's).

You very quickly have the disk heahs spending most of their time seeking, and end up with WORSE overall performance. "Some" type of throttling to match the request rate with the performance of the hardware is usually a good thing.

The trivial posting I gave can easily be expanded on a perfile name basis along with a count request. In this case the lock would only be impacted when multiple requewsts are for the same file, or if the number of simultanious requests exceeds a threshold.

I have successfully used variations on this technique for LARGE server farms to good effect.