Every ASP.NET application - a multithreaded windows app?

P

Pavils Jurjans

Hello,

I wanted to get some light in the subject. As I develop ASP.NET
applications, it's necessary to understand how exactly the server-[multiple
clients] communication happens. It seems like initially application is
"sleeping", and it is not loaded in the memory. Then, after very first
request to the app, it is compiled (aspx files), loaded into memory, and
executed. Then, a separate thread is issued to serve my page request, and it
takes care for me receiving all the necessary html+headers. So, could I
assume that every basic ASP.NET application is actually a multithreaded
windows app which happens to listen on port 80?

I am going to research possibilities of issuing new threads from within
ASP.NET application, to process some complex tasks, and letting users use
application (browse pages), and once the complex task is processed, the
result is accessible via normal forms. It would be interesting to know some
issues that could arise in such endeavors.

Thanks,

Pavils
 
J

John Saunders

Pavils Jurjans said:
Hello,

I wanted to get some light in the subject. As I develop ASP.NET
applications, it's necessary to understand how exactly the server-[multiple
clients] communication happens. It seems like initially application is
"sleeping", and it is not loaded in the memory. Then, after very first
request to the app, it is compiled (aspx files), loaded into memory, and
executed. Then, a separate thread is issued to serve my page request, and it
takes care for me receiving all the necessary html+headers. So, could I
assume that every basic ASP.NET application is actually a multithreaded
windows app which happens to listen on port 80?

I am going to research possibilities of issuing new threads from within
ASP.NET application, to process some complex tasks, and letting users use
application (browse pages), and once the complex task is processed, the
result is accessible via normal forms. It would be interesting to know some
issues that could arise in such endeavors.

Don't do it.

Ok, you can do it if you absolutely have to, but you should try to avoid it.
ASP.NET does not play well with user-created threads. In particular, ASP.NET
has control over the HttpContext and everything it references (Request,
Response, etc.). In particular, you cannot make assumptions about the
contents of these objects after a page request has completed.

Now, there are people who have successfully done the kind of thing you're
talking about. Do a Google search in this newsgroup for "Please wait", or
"progress", and you'll see many requests like yours. They come down to
starting a thread of your own to process your long-running request (the
thread should _not_ reference the HttpContext), then having the client side
check for progress periodically. This may be done by using a meta refresh
tag to refresh a "Please wait" page, or XMLHTTP to a server-side web
service, or the equivalent.
 
L

Lenard Gunda

Hi!

You could consider this solution. Create a dummy page (say loading.asp -
although the rest is written using ASP.NET, this simple file does not need
the weight of that :) ), that will receive the real URL you wish to load
(which will do the processing). This file only needs to render, and then in
<body onload=""> use javascript to redirect to your new page (
window.location = "newurl" ). I found out that the order in which things
should be, in order to work properly, is this:

<html>
<head> ... </head>
<script>

function myredir ()
{
window.location = "new url"
}

</script>
<body onload="myredir();">
....
</body>
</html>

Now, in the body, you could place an animated GIF, that displays a progress
bar, or something animation (working, loading, etc). What will happen, is
that the page gets rendered correctly, and then onload gets called, which
opens the new URL. But, while that one is processing (a long request, for
example, in ASP.NET), the old page will still be displayed. The order above
is important, because for me, the GIF only kept animating, if the script
section was between head and body tags.

You could use ASP to create one redirecting page to many other locations,
while displaying the progress image. And this way the user still sees, that
something is going on, not just a page loading (and if displayed the browser
icon animating). Although he cannot browse during this.

-Lenard
 
P

Pavils Jurjans

Yeah, that's the simple way of doing things,

but there's the problem, that user can not browse the pages further, so that
is not fine. Also, the animated gif showing "loading" and animating
hourglass, is not enough, because I want to provide detailed information
about the percentage of process completed, as well as current estimate, when
it will be finished, and actually enable a number of such processes running.

I think I will do some research on independent thread launching, and I will
also look how I can access the sessionstate object that is associated with
the user that launched the process. It is clear, that it's complex and all,
but I'm not meek either.It will just require extensive research on how to
access certain session (for reading only), and how to report back to the
application (perhaps database).

-- Pavils

Lenard Gunda said:
Hi!

You could consider this solution. Create a dummy page (say loading.asp -
although the rest is written using ASP.NET, this simple file does not need
the weight of that :) ), that will receive the real URL you wish to load
(which will do the processing). This file only needs to render, and then in
<body onload=""> use javascript to redirect to your new page (
window.location = "newurl" ). I found out that the order in which things
should be, in order to work properly, is this:

<html>
<head> ... </head>
<script>

function myredir ()
{
window.location = "new url"
}

</script>
<body onload="myredir();">
...
</body>
</html>

Now, in the body, you could place an animated GIF, that displays a progress
bar, or something animation (working, loading, etc). What will happen, is
that the page gets rendered correctly, and then onload gets called, which
opens the new URL. But, while that one is processing (a long request, for
example, in ASP.NET), the old page will still be displayed. The order above
is important, because for me, the GIF only kept animating, if the script
section was between head and body tags.

You could use ASP to create one redirecting page to many other locations,
while displaying the progress image. And this way the user still sees, that
something is going on, not just a page loading (and if displayed the browser
icon animating). Although he cannot browse during this.

-Lenard




Pavils Jurjans said:
Hello,

I wanted to get some light in the subject. As I develop ASP.NET
applications, it's necessary to understand how exactly the server-[multiple
clients] communication happens. It seems like initially application is
"sleeping", and it is not loaded in the memory. Then, after very first
request to the app, it is compiled (aspx files), loaded into memory, and
executed. Then, a separate thread is issued to serve my page request,
and
it
takes care for me receiving all the necessary html+headers. So, could I
assume that every basic ASP.NET application is actually a multithreaded
windows app which happens to listen on port 80?

I am going to research possibilities of issuing new threads from within
ASP.NET application, to process some complex tasks, and letting users use
application (browse pages), and once the complex task is processed, the
result is accessible via normal forms. It would be interesting to know some
issues that could arise in such endeavors.

Thanks,

Pavils
 
L

Lenard Gunda

Hi!

You could also do your processing in a normal application, or perhaps a
Windows Service, that would be running all the time on the server, and your
web application would give it the request. Under C#, creating these should
be very easy, and they can be used to support your web application quite
well (I myself did something similar, although not because of lengthy
processing, but because of other limitations). You can then refresh your
page in certain intervals, and have it request state information from
whoever is processing the request, and if it is complete, display the
results.

And just something that came into my mind (dunno how useful it would be).
Maybe you should take a look at this page:

http://chat.ircnet.org/

It is a web based IRC client. It too, somehow updates to the client, what
has happened (a new message received), maybe you get ideas from that (I
think's it's implemented with CGI on the server side). You might get your
hands on freely available sources for web based irc.

-Lenard


Pavils Jurjans said:
Yeah, that's the simple way of doing things,

but there's the problem, that user can not browse the pages further, so that
is not fine. Also, the animated gif showing "loading" and animating
hourglass, is not enough, because I want to provide detailed information
about the percentage of process completed, as well as current estimate, when
it will be finished, and actually enable a number of such processes running.

I think I will do some research on independent thread launching, and I will
also look how I can access the sessionstate object that is associated with
the user that launched the process. It is clear, that it's complex and all,
but I'm not meek either.It will just require extensive research on how to
access certain session (for reading only), and how to report back to the
application (perhaps database).

-- Pavils

Lenard Gunda said:
Hi!

You could consider this solution. Create a dummy page (say loading.asp -
although the rest is written using ASP.NET, this simple file does not need
the weight of that :) ), that will receive the real URL you wish to load
(which will do the processing). This file only needs to render, and then in
<body onload=""> use javascript to redirect to your new page (
window.location = "newurl" ). I found out that the order in which things
should be, in order to work properly, is this:

<html>
<head> ... </head>
<script>

function myredir ()
{
window.location = "new url"
}

</script>
<body onload="myredir();">
...
</body>
</html>

Now, in the body, you could place an animated GIF, that displays a progress
bar, or something animation (working, loading, etc). What will happen, is
that the page gets rendered correctly, and then onload gets called, which
opens the new URL. But, while that one is processing (a long request, for
example, in ASP.NET), the old page will still be displayed. The order above
is important, because for me, the GIF only kept animating, if the script
section was between head and body tags.

You could use ASP to create one redirecting page to many other locations,
while displaying the progress image. And this way the user still sees, that
something is going on, not just a page loading (and if displayed the browser
icon animating). Although he cannot browse during this.

-Lenard




Pavils Jurjans said:
Hello,

I wanted to get some light in the subject. As I develop ASP.NET
applications, it's necessary to understand how exactly the server-[multiple
clients] communication happens. It seems like initially application is
"sleeping", and it is not loaded in the memory. Then, after very first
request to the app, it is compiled (aspx files), loaded into memory, and
executed. Then, a separate thread is issued to serve my page request,
and
it
takes care for me receiving all the necessary html+headers. So, could I
assume that every basic ASP.NET application is actually a multithreaded
windows app which happens to listen on port 80?

I am going to research possibilities of issuing new threads from within
ASP.NET application, to process some complex tasks, and letting users use
application (browse pages), and once the complex task is processed, the
result is accessible via normal forms. It would be interesting to know some
issues that could arise in such endeavors.

Thanks,

Pavils
 
J

John Saunders

Pavils Jurjans said:
Yeah, that's the simple way of doing things,

but there's the problem, that user can not browse the pages further, so that
is not fine. Also, the animated gif showing "loading" and animating
hourglass, is not enough, because I want to provide detailed information
about the percentage of process completed, as well as current estimate, when
it will be finished, and actually enable a number of such processes running.

I think I will do some research on independent thread launching, and I will
also look how I can access the sessionstate object that is associated with
the user that launched the process. It is clear, that it's complex and all,
but I'm not meek either.It will just require extensive research on how to
access certain session (for reading only), and how to report back to the
application (perhaps database).

Your independent threads should _not_ touch the Session object. It's ok if
they touch objects which are stored in Session, but they shouldn't touch
Session itself. ASP.NET owns Session, and will not consult your independent
threads before destroying or invalidating Session.

All due respect, but it sounds like you're about to create a maintenance
nightmare. This is not the sort of thing that a web application is
especially good at. This is much more the sort of thing one does in a
Windows application (as I recall, you accused ASP.NET of being a Windows
application which listens on port 80).

I recommend that you be very careful about using rich-client ideas in a thin
client world.
 
P

Pavils Jurjans

Hello John,
Your independent threads should _not_ touch the Session object. It's ok if
they touch objects which are stored in Session, but they shouldn't touch
Session itself. ASP.NET owns Session, and will not consult your independent
threads before destroying or invalidating Session.

I am afraid there is some miscommunication here. In my searches, I've found
this link http://www.fawcette.com/vsm/2002_11/magazine/features/chester/
Which actually does exactly what I am talking about. It generates a list of
prime numbers in background, letting you to use application (well, in the
example just basic refresh, nevertheless it can be defined as "using
application"), and also storing data in Session variable, using SyncLock vb
statement (lock in C#). While that may not be necessarily the best way to
exchange information with application, it seems to be valid way. I have not
studied whether such writing in Session variable from the thread code keeps
the session live or there is a risk that session expires and the thread can
not write to it's variable. However, even then the code could check for
availability of the Session property. what do you actually mean with saying
"touch Session itself"?
All due respect, but it sounds like you're about to create a maintenance
nightmare. This is not the sort of thing that a web application is
especially good at. This is much more the sort of thing one does in a
Windows application (as I recall, you accused ASP.NET of being a Windows
application which listens on port 80).

I recommend that you be very careful about using rich-client ideas in a thin
client world.

John, this is the second mail where you keep telling "don't do this" and
"consider not doing that". I dare to say that this is not the way how
problems are solved and discoveries are made. I am not a newbie who has to
be taught not to run with scissors. All I want is to be able to provide
quality interface to my web applications. If that requires advanced
techniques, that's fine, because all the complexities always can be
abstracted away in good OO framework and debugged to perfection. If there
are problematic issues, they can be resolved. But, unless there's a distinct
bug in ASP.NET framework that is known to cause unexpected behaviour, or
memory leak, or whatever else, when using new threads that do their work in
background, I don't see point in not using such approaches, if there is such
need. An alternative, of course, is to use separate parallel process that is
running on the server (or other server on network), and send task to it, and
let it do the processing. But, that is pretty disconnected solution and I'd
prefer the complex code to be run in the environment of my application,
where it actually belongs.
 
J

John Saunders

Pavils Jurjans said:
Hello John,


I am afraid there is some miscommunication here. In my searches, I've found
this link http://www.fawcette.com/vsm/2002_11/magazine/features/chester/
Which actually does exactly what I am talking about. It generates a list of
prime numbers in background, letting you to use application (well, in the
example just basic refresh, nevertheless it can be defined as "using
application"), and also storing data in Session variable, using SyncLock vb
statement (lock in C#). While that may not be necessarily the best way to
exchange information with application, it seems to be valid way. I have not
studied whether such writing in Session variable from the thread code keeps
the session live or there is a risk that session expires and the thread can
not write to it's variable. However, even then the code could check for
availability of the Session property. what do you actually mean with saying
"touch Session itself"?

For instance, do not pass Session in the constructor of the thread class:

public class MyThread {
private HttpSessionState _session;
public MyThread(HttpSessionState session)
{
_session = session;
}

// Also, don't do this:
public void Start(HttpSessionState session)
{
_session =session;
_thread = new Thread(new ThreadStart(MyThreadStart));
_thread.Start();
}

private void MyThreadStart()
{
// Do thread's work:
_session["key"] = value; // Wrong
}

}

The basic problem is that the HttpSessionState instance in Session is owned
by ASP.NET, which knows nothing at all about your extra thread. ASP.NET is
free to do whatever it likes to that instance, as long as it matches its
documentation. In particular, there is no reason to believe that the session
will be kept alive based on access by your thread. It's more likely to be
kept alive by page requests.

You have to be very careful with multithreading, and especially careful when
you're doing things which are not documented by Microsoft. You may very well
create test code which seems to work, and your application may even seem to
work for a while, but you are likely to see strange errors which will be
very difficult to diagnose.

Trust me when I say that assumptions and threads do not go well together!
I've seen cases where a threading bug was not visible until we ran our tests
on an 8-CPU system, maxed out at 8x100% CPU time usage. On examination, the
bugs have almost always been due to assumptions for which there was no
justification.
John, this is the second mail where you keep telling "don't do this" and
"consider not doing that". I dare to say that this is not the way how
problems are solved and discoveries are made.

You're mistaken. This is how people learn to listen to those who've made
these mistakes before! Please feel free to learn. ;-)
I am not a newbie who has to
be taught not to run with scissors. All I want is to be able to provide
quality interface to my web applications. If that requires advanced
techniques, that's fine, because all the complexities always can be
abstracted away in good OO framework and debugged to perfection.

These are not "advanced" techniques - they are hacks. There is a reason you
don't see many examples of these "advanced techniques" from Microsoft.

You are not working with Windows programs here. You are working with a
client-server framework which means to have control of how requests and
responses are handled. In particular, it makes no provision for your extra
threads. If it appears to work, you will be lucky. If it actually works,
you'll be very, very, lucky. If it actually works in future releases, you
must be a holy man.

BTW, "debugging" is not what you should be looking at. You should be looking
at exhaustive testing under heavy load, on a multi-processor server (4 CPUs
minimum). In particular, be sure to test your code to see how it works when
the Session state expires, and also, see how it works when the
HttpSessionState instance has been Disposed or worse. Note the warning in
the documentation that instance methods of that class are not thread-safe.
If there
are problematic issues, they can be resolved. But, unless there's a distinct
bug in ASP.NET framework that is known to cause unexpected behaviour, or
memory leak, or whatever else, when using new threads that do their work in
background, I don't see point in not using such approaches, if there is such
need.

It's not a bug, it's a feature. That's how it's designed. If you don't like
that, then you should create your own multithreaded Windows program which
listens on port 80.
An alternative, of course, is to use separate parallel process that is
running on the server (or other server on network), and send task to it, and
let it do the processing. But, that is pretty disconnected solution and I'd
prefer the complex code to be run in the environment of my application,
where it actually belongs.

I'm really not certain from what you say, that you understand the
disconnected, client/server, request/response nature of ASP.NET
applications. Disconnected is exactly what they are, and exactly what you
should be looking at. Having the long-running thread in another process is
_exactly_ the sort of thing you should be doing.

I have always found it to be a mistake to try to treat ASP.NET applications
as though they were standard Windows applications. They're not.
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top