0

I got started with threads Thread.Start() recently and Long Running Tasks and noticed several request related issues.

EDIT

What would you suggest to provide the user a feedback while the job is being processed, make efficient use of the thread pool and make use of HttpContext if possible?

maxbeaudoin
  • 6,546
  • 5
  • 38
  • 53
  • I'm confused, why do you believe that HttpContext.Current isn't thread safe? – Keith Adler Jul 24 '09 at 17:36
  • Its mostly read only, I believe it's thread safe but passing a reference of HttpContext to an other thread is dangerous, I will eventually expire. Using HttpContext in my assemblies is dangerous as well as it is always null if I decide to use theses assemblies in another thread, with no HttpContext. – maxbeaudoin Jul 24 '09 at 17:44

3 Answers3

3

You are quite possibly making a mistake in your use of threads in an ASP.NET application. Are you using asynchronous pages, or are you using new Thread().Start? The latter is a mistake, and can get you into some of those problems with HttpContext, when the request is complete, but the thread is still running.

Please edit your question to give more detail on what you're doing with threads.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • Thank you. You _are_ making a mistake. Long-running tasks should not be performed as part of the web application. They should be sent to another service for execution. The ASP.NET infrastructure is not made to deal with long-running tasks. – John Saunders Jul 28 '09 at 13:54
  • What do you suggest to provide the user a feedback while the job is being processed, make efficient use of the thread pool and make use of HttpContext if possible? – maxbeaudoin Jul 29 '09 at 13:35
  • You can't provide feedback _to_ the user. The user is the browser. The browser can use AJAX to query the status of the operation. You cannot use `HttpContext` for this. – John Saunders Jul 29 '09 at 13:46
  • OK let's just say, a "Please Wait..." while the job is being processed. Asynch. pages will block rendering no!? – maxbeaudoin Jul 29 '09 at 14:05
  • No! Where do you _get_ these ideas? And a "Please wait" is just making a div visible. It could even contain one of those cool animated gif's to fool the user into thinking something is happening. – John Saunders Jul 29 '09 at 14:12
  • That's the canonical article on async pages. Where do you see it saying that this blocks rendering? The word "blocks" doesn't even appear in the article. – John Saunders Jul 29 '09 at 16:01
  • "Between the time Begin returns and End gets called, the request-processing thread is free to service other requests, and until End is called, rendering is delayed"
    But I believe you if you say that I won't have a white loading page while the long running task is being processed. ;p
    – maxbeaudoin Jul 29 '09 at 16:26
  • No, I thought I'd gotten you away from "long-running task in ASP.NET". The task does not belong in ASP.NET. Move it out to a separate service. Have the page query for completion status or progress, and update an AJAX UI on that basis. Async pages are not for "long" running tasks. They're for tasks that will take 2 seconds. The idea is to not tie up worker threads for 2 seconds, when they'll just be blocked for 1.8 seconds. – John Saunders Jul 29 '09 at 16:33
  • Sorry for giving you so much troubles. So a Web Service processing the task and somehow a Status Class plus an AJAX UI? – maxbeaudoin Jul 29 '09 at 17:07
  • If it was trouble, I wouldn't be this nice. :-) I didn't mean a **web** service. I meant a small **Windows** service. Communicate between the two using either WCF or MSMQ (preferably WCF, hosted in the service). The communication would just pass the work to it. It could maintain a list or even MSMQ queue of completed requests. A separate AJAX call to the page would query the service to ask for status. Could be simpler if all you need is a working/done/error status, and not details. – John Saunders Jul 29 '09 at 17:13
  • I'll take that as an answer ;p. Thanks a lot! – maxbeaudoin Jul 29 '09 at 17:17
0

For accessing data:

For data like Server.Identity.Name, I think collecting that information beforehand and passing it to your async code is a good approach. Its good decoupling as that code now only depends on those few properties.

For accessing behavior:

How are you using threads with ASP.NET? The two approaches that work are to implement and register IAsyncHttpHandler, or you're call Page.AddOnPreRenderCompleteAsync() from some ASP.NET page.

For IAsyncHttpHandler, the callback you implement is passed an HttpContext. You should be able to use that referenced context from any thread until you indicate to ASP.NET that request processing has finished. Of course you should only use that reference from one thread a time.

For Page.AddOnPreRenderCompleteAsync, it should be safe to call Page.Context from your callbacks under the same conditions.

For the existing code you have in App_Code that uses HttpContext.Current, you need to refactor that so the code takes the HttpContext as an input parameter. Existing code can pass in HttpContext.Current, new code you're writing from threads can pass in one of the contexts described earlier in this answer.

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
-1

HttpContext.Current property of HttpContext object is static. And it can be used when in different threads or in the assemblies in the App_Code. But, it returns HttpContext object of the current Request.

All static properties of HttpContext are thread safe. And all the instance properties of HttpContext are not thread safe.

Pradeep Kumar
  • 1,281
  • 7
  • 9
  • 1
    The result of HttpContext.Current depends on what thread your in, so your advice is not correct. – Frank Schwieterman Jul 24 '09 at 18:19
  • Please note that I have mentioned, "But, it returns HttpContext object of the current Request." So, if you are not in the context of request (out of boundary) HttpContext.Current will obviously return null no matter what thread you are in. – Pradeep Kumar Jul 24 '09 at 18:35