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.