Click here to Skip to main content
15,887,083 members
Home / Discussions / ASP.NET
   

ASP.NET

 
AnswerRe: virtual directories c# Pin
N a v a n e e t h25-May-08 20:05
N a v a n e e t h25-May-08 20:05 
AnswerRe: virtual directories c# Pin
Laddie25-May-08 19:58
Laddie25-May-08 19:58 
GeneralRe: virtual directories c# Pin
Abhijit Jana25-May-08 20:01
professionalAbhijit Jana25-May-08 20:01 
GeneralRe: virtual directories c# Pin
N a v a n e e t h25-May-08 20:04
N a v a n e e t h25-May-08 20:04 
GeneralRe: virtual directories c# Pin
Laddie25-May-08 20:13
Laddie25-May-08 20:13 
GeneralRe: virtual directories c# Pin
N a v a n e e t h25-May-08 20:55
N a v a n e e t h25-May-08 20:55 
QuestionCross Application Authentication (Domain Read/Set problem) Pin
RCoate25-May-08 15:15
RCoate25-May-08 15:15 
QuestionBest Practice: Thread Management: Making Asynchronous WebRequest from the server Pin
Daniel Magliola25-May-08 14:28
Daniel Magliola25-May-08 14:28 
Hello everyone,

I have a query that's probably quite common, but there's a part of how Threads are managed that I don't quite fully grasp, so i'm wondering what's the best way to solve my scenario.

The functional overview is quite simple: My site visitor wants to search, he enters a query, I forward that query to a 3rd party catalog that searches for me, and I return the results to the client.
The search works over AJAX, so I'm receiving the request on an ASHX handler, and returning the HTML that the JS will then put into a div directly.
This 3rd party service is expected to take a while to respond (many seconds)

My question is how to handle the threads on the server to avoid a bottleneck.
The obviously simplest way is to have the ASHX open a WebRequest to the 3rd party catalog directly. The obvious problem is, i can only have 25 queries running simultaneously in that case (i'm picking 25 as the number of threads in my pool from now on. I know this can be changed but that's not the point.)
I want to release these threads so they can keep handling other requests while the searches I spawned are pending, so the first thing I'm doing is using an IHttpAsyncHandler
In the method where I call the 3rd party URL, i'm using HttpWebRequest.BeginGetResponse (with a callback), so that part is handled Async too.

My question is...
When I call BeginGetResponse, I can immediately free the thread that I'm in and return it to the pool.
However, when I do that, am I not spawning a new thread that is alive while the request goes on, and ends up calling my callback once it finishes?

If I AM spawing this new thread, doesn't this consume one thread from the pool too, and I'm actually getting a net effect of the same as going synchronous?
If I am NOT spawning a new thread, then how does my callback get called? Who is checking whether this async method I started is finished? (This is the main part of the puzzle that I don't quite grasp)

If a response from the 3rd party catalog takes forever, could I potentially have 1000 of these async WebRequest methods pending a response at the same time, and still be using no threads (or very few) from the 25-thread pool?
Or will I only be able to have 25 of these waiting for a response from the catalog, and the rest will be queued up by IIS?


Below I'm attaching the code that I wrote that shows what i'm doing.
This is obviously oversimplified. I left the "architectural" stuff, and removed all the things specific to my case.

Am I doing things right? Should I be using an Async HTTP Handler, AND calling BeginGetResponse?
Is there a better way?


Thank you very much for your answers!

Daniel
----------------------------------------------------------------------------------------------

<![CDATA[<%@ WebHandler Language="VB" Class="SearchHttpHandler" %>]]>

Option Strict On

Imports System.Threading
Imports System.IO
Imports System.Net

Public Class SearchHttpHandler
	Implements IHttpAsyncHandler
	Implements IReadOnlySessionState

	'---------------------------------------------------------------------------------------
	
	Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
	End Sub

	
	'---------------------------------------------------------------------------------------

	Function BeginProcessRequest(ByVal context As System.Web.HttpContext, ByVal cb As System.AsyncCallback, ByVal extraData As Object) As System.IAsyncResult Implements IHttpAsyncHandler.BeginProcessRequest

		context.Response.Write("Started on thread: " & _
			Threading.Thread.CurrentThread.ManagedThreadId & " - " & _
			Threading.Thread.CurrentThread.IsThreadPoolThread.ToString & "<br />")

		'Instantiate the AsyncResult object that'll give us a hold to the context and the callback		
		Dim theAsyncResult As New SearchAsyncResult(context, cb, extraData)
		theAsyncResult.Search()
		Return theAsyncResult
				
	End Function

	'---------------------------------------------------------------------------------------

	Sub EndProcessRequest(ByVal result As System.IAsyncResult) Implements IHttpAsyncHandler.EndProcessRequest
		
		Dim theObj As SearchAsyncResult = DirectCast(result, SearchAsyncResult)
		theObj.Context.Response.Write("Ended on thread: " & _
			Threading.Thread.CurrentThread.ManagedThreadId & " - " & _
			Threading.Thread.CurrentThread.IsThreadPoolThread.ToString)
		
	End Sub

	'---------------------------------------------------------------------------------------

	Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
		Get
			Return False
		End Get
	End Property

End Class

'======================================================================================
'======================================================================================

Public Class SearchAsyncResult
	Implements IAsyncResult
	
	Public Context As HttpContext

	Private mASPNETCallback As AsyncCallback
	Private mExtraData As Object
	Private mIsCompleted As Boolean
	Private mAsyncWaitHandle As ManualResetEvent
	Private mRequest As HttpWebRequest
	
	Private mQuery As String
	
	'-------------------------------------------------------------
	
	Public Sub New(ByVal context As HttpContext, ByVal ASPNETCallback As AsyncCallback, ByVal ExtraData As Object)
		Me.Context = context
		mASPNETCallback = ASPNETCallback
		mExtraData = ExtraData
	End Sub

	'-------------------------------------------------------------

	Public Sub Search()
		
		If Context.Request.QueryString("q") IsNot Nothing Then
			mQuery = Context.Request.QueryString("q")
		End If
				
		'Return "No Results" if there is no query
		If mQuery = "" Then
			Context.Response.Write("No Results")
			CompleteRequest()
			Exit Sub
		End If
		
		'Otherwise, make an async call
		Dim URL As String = "xxxxxxx?q=" & mQuery
		mRequest = DirectCast(WebRequest.Create(URL), HttpWebRequest)

		mRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
		mRequest.Method = "GET"

		mRequest.BeginGetResponse(AddressOf SearchCallback, Nothing)
		
	End Sub
	
	'-------------------------------------------------------------

	Private Sub SearchCallback(ByVal ar As IAsyncResult)
		
		Dim WebResp As WebResponse = mRequest.EndGetResponse(ar)
		Dim sReader As New StreamReader(WebResp.GetResponseStream())
		Dim result As String = sReader.ReadToEnd()
		
		Context.Response.Write(result)
		
		CompleteRequest()
		
	End Sub
	
	'-------------------------------------------------------------
	
	Private Sub CompleteRequest()
		
		mIsCompleted = True
		SyncLock Me
			If mAsyncWaitHandle IsNot Nothing Then
				mAsyncWaitHandle.Set()
			End If
		End SyncLock
		If mASPNETCallback IsNot Nothing Then
			mASPNETCallback(Me)
		End If
		
	End Sub
	
	'---------------------------------------------------------------------
	
#Region "Implementation of IAsyncResult dummy members"
	
	Public ReadOnly Property AsyncState() As Object Implements System.IAsyncResult.AsyncState
		Get
			Return mExtraData
		End Get
	End Property

	Public ReadOnly Property AsyncWaitHandle() As System.Threading.WaitHandle Implements System.IAsyncResult.AsyncWaitHandle
		Get

			SyncLock Me
				If mAsyncWaitHandle Is Nothing Then
					mAsyncWaitHandle = New ManualResetEvent(False)
				End If
				Return mAsyncWaitHandle
			End SyncLock

		End Get
	End Property

	Public ReadOnly Property CompletedSynchronously() As Boolean Implements System.IAsyncResult.CompletedSynchronously
		Get
			Return False
		End Get
	End Property

	Public ReadOnly Property IsCompleted() As Boolean Implements System.IAsyncResult.IsCompleted
		Get
			Return mIsCompleted
		End Get
	End Property
	
#End Region

	'---------------------------------------------------------------------

End Class	'SearchAsyncResult

QuestionFormView Insert record containing DropDownList value Pin
thowra25-May-08 8:48
thowra25-May-08 8:48 
QuestionGet the number of response bytes of an HTTP Response Pin
Marco225025-May-08 5:20
Marco225025-May-08 5:20 
Questionrepresenting dataset after receiving from webservice Pin
Faysal25-May-08 4:53
Faysal25-May-08 4:53 
AnswerRe: representing dataset after receiving from webservice Pin
CodingYoshi25-May-08 9:06
CodingYoshi25-May-08 9:06 
GeneralRe: representing dataset after receiving from webservice Pin
Faysal25-May-08 17:10
Faysal25-May-08 17:10 
Questionformat of date Pin
ptvce24-May-08 23:35
ptvce24-May-08 23:35 
AnswerRe: format of date Pin
gnjunge25-May-08 1:30
gnjunge25-May-08 1:30 
AnswerRe: format of date Pin
derm225-May-08 7:15
derm225-May-08 7:15 
Questioncontrol & access data to a web page programmatically Pin
caradri24-May-08 22:27
caradri24-May-08 22:27 
AnswerRe: control & access data to a web page programmatically Pin
doWhileSomething25-May-08 3:10
doWhileSomething25-May-08 3:10 
QuestionIssue with ajax Update panel and Javascript Pin
Sajid A.24-May-08 22:21
Sajid A.24-May-08 22:21 
QuestionAsp.Net 2 Arabic Language Issue Pin
Aldorado24-May-08 9:16
Aldorado24-May-08 9:16 
AnswerRe: Asp.Net 2 Arabic Language Issue Pin
gnjunge25-May-08 1:19
gnjunge25-May-08 1:19 
GeneralRe: Asp.Net 2 Arabic Language Issue Pin
Aldorado25-May-08 2:03
Aldorado25-May-08 2:03 
AnswerRe: Asp.Net 2 Arabic Language Issue Pin
Mogaambo25-May-08 4:07
Mogaambo25-May-08 4:07 
GeneralRe: Asp.Net 2 Arabic Language Issue Pin
Aldorado25-May-08 4:16
Aldorado25-May-08 4:16 
GeneralRe: Asp.Net 2 Arabic Language Issue Pin
gnjunge25-May-08 11:03
gnjunge25-May-08 11:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.