how to handle multiple http requests from a single client such that it is handled by single Asp.net thread. When PageAsyncTask or TPL is not an option as it does create a new thread. Code snipet will be of great help.
Each separate HTTP request will be executed on a potentially separate thread.
You have no control over which thread execution of your ASP.Net page is scheduled on.
I do not believe this can be accomplished.
Think about why you are trying to do this. Do you need to share some information between the various HTTP requests? If so, consider using a session or a cookie to manage that information.
Related
I have the need to have an option to enabled deep debug logging using log4net. I am familiar with how classic ASP.Net handles threads, but I wondered how threads work with ServiceStack. The goal would be to use %Thread to group requests together in the log. I think the only problem is that there is likely a thread pool and the %thread id will be reused on subsequent requests.
Really what I am looking for is a single unique id I can expose to log4net so I can group the entire logging of a single request together when building a report.
Can anyone lend some guidance?
See this page on concurrency in ServiceStack, i.e. ServiceStack when hosted in ASP.NET doesn't create any new threads itself, requests are simply handled on the same IIS/Nginx/etc ASP.NET HTTP WebWorker that handles the request. Ultimately control of the Thread Pool and thread instances is up to the underlying ASP.NET but its common for them to re-use the same threads to handle different requests.
Use IHttpRequest.Items whenever you want to share any data throughout the lifetime of a single request, e.g. you could simply assign a Guid at the start of the request using a PreRequestFilters with:
this.PreRequestFilters.Add((req, res) => req.Items["ReqId"] => Guid.NewGuid());
Which lasts the entire lifetime of the request and the same instance of IHttpRequest is available in all filters, services, views, etc.
The problem is as follows:
An external server sends incoming SMS messages converted to HTTP requests into my sometimes very time-consuming .aspx page. If no response is returned to the external server in 20 seconds, this is considered as an timeout and the same message is sent to my aspx page again (and maybe again....)
The optimal solution for me would be that the aspx page reads the incoming message (as an HTTP request to the aspx page), starts the processing of the message in another thread, and immediately renders response back to the external server. The external server has no interest in other stuff than the HTTP status (normally 200). When the processing of the message is completed this results in an entry into the log file of the application.
The processing of the message is done by making another web request to an aspx page, and I have tried to use the BeginGetResponse method for the web request, and have created a handler for handling of the completed web request to the processing page. The problem is that the handler seems to not be called, most likely because the aspx page's lifecycle is ended before the asynchrounous web request is completed.
Has anyone any good solution for this problem? I have also looked at the async page model, but this also seems to not be a solution for me because the response should be returned to the external server before the processing of the message is completed.
Regards, Eivind
I'd be very wary of using threads in ASP.Net in this manner. Using them to take advantage of multiple cores is one thing. Using them to set up some kind of concurrent response technique seems like a recipe for disaster. Especially when there is a far more elegant solution.
Your ASP.Net application should merely take the message and toss it in a database and send the success reply. It's job is done. The job of delivering the message should be handled by some kind of service or daemon. Windows Services are kind of a pain to build and maintain so perhaps just a scheduled task that runs every 30 seconds or so checking for queued messages in the DB would suit your purposes just fine.
I've seen a lot of people try to use threads in ASP.Net when they really should just be creating a background service. The results are never as reliable as you would hope.
Async page model is definitely not the solution. Have you tried using the unload event to do EndRequest? I really don't know if that would work but it is worth a try. The most robust way is to use Windows Service to run the async request.
Looking at a very simple web project, hosted in IIS, with one simple aspx page, executing some code (get some data from a db and populate some controls), which of the following is true:
each page request shares the same instance of the codebehind class.
or each page request runs in its own instance of the codebehind class.
Does one thread/instance run against each aspx page. Or does one thread/instance cover multiple pages?
Im trying to understand, in a simple web project, that receives 100 page requests, will they run consecutively one after the other, or multiple instances/threads for each request?
Each request gets a new instance of the code-behind class.
One instance of the code-behind class serves one request.
Two requests at different points in time may run on the same thread from the thread pool.
Two requests that runs in parallell gets one thread each (I think; not 100% sure on if there are some corner cases that I am not aware of regarding the threading).
So, a web server can handle several requests in parallell, but there is of course a limit on how many requests that can be served at the same time.
There is one instance of the code behind class for each request.
Well, actually it's an instance of the aspx page class, that inherits from the code behind class. (That's why you are using the protected keyword for event handlers in code behind, so that the inheriting class can access them.)
There is also the case where you do a Server.Transfer or Server.Execute, then the request is transfered to another page instance.
There are several threads running in the IIS handling requests, and usually one request is handled in one thread, but a request can be moved from one thread to another in some situations.
If 100 requests arrive at the server, it will start processing a few of them in separate threads, and put the rest of them in a queue. Noteworthy is that the server will only process one page at a time from each user, so unless you use sessionless pages (to make them anonymous) it will not process two pages for the same user in parallel threads, which makes the whole threading part a lot easier.
Maybe take a look at asynchronous ASP.NET?
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
Normally a new thread is assigned to a new request.
"A normal, or synchronous, page holds onto the thread for the duration of the request, preventing the thread from being used to process other requests."
We have an application that hits a web service successfully, and the data returned updates our DB. What I'm trying to do is allow the user to continue using other parts of our web app while the web service processes their request and returns the necessary data.
Is this asynchronous processing? I've seen some console app samples on the msdn site, but considering this is a web form using a browser I'm not sure those samples apply. What if the user closes the browser window mid request? Currently we're using the Message Queue which "waits" for the web service to respond then handles the DB update, but we'd really like to get rid of that.
I'm (obviously) new to async requests and could use some help figuring this out. Does anyone have some code samples or pertinent articles I could check out?
Yes, what you're describing is async processing.
The best solution depends to some degree on the nature of the web services call and how you want to handle the results. A few tips that might help:
One approach is to send a request from the initial web request to a background thread. This works best if your users don't need to see the results of the call as soon as it completes.
Another approach is to have your server-side code make an async web services call. This is the way to go if your users do need to see the results. The advantage of an async call on the server side is that it doesn't tie up an ASP.NET worker thread waiting for results (which can seriously impair scalability)
Your server-side code can be structured either as a web page (*.aspx) or a WCF service, depending on what you want to have it return. Both forms support async.
From the client, you can use an async XMLHTTP request (Ajax). That way, you will receive a notification event when the call completes.
Another approach for long-running tasks is to write them to a persistent queue using Service Broker. This works best for things that you'd like users to be able to start and then walk away from and see the results later, with an assurance that the task will be completed.
In case it helps, I cover each of these techniques in detail in my book, along with code examples: Ultra-Fast ASP.NET.
If you're not blocking for a method return you're doing asychronous processing. Have a look at Dino Esposito's article on using AJAX for server task checking.
You can perform asynchronous web service calls using both Web Service Enhancements (WSE) and Windows Communication Foundation (WCF) in your C# code. WSE is discontinued, so its use is not recommended. Generically speaking, if you were to terminate program execution in the middle of an asynchronous call before the response returned, nothing bad would happen; the client would simply not process the result, but the web service would still be able to perform its processing to completion.
If your client web application is responsible for updating the DB, then without anything else in your client code, quitting in the middle of an asynchronous operation would mean that the DB was not updated. However, you could add some code to your client application that prevented the browser from quitting entirely while it is waiting for an asynchronous response while preventing new web service calls from being run after Close is called (using Javascript).
You have 2 distinct communications here: (1) from web browser to web application and (2) from web application to web service.
diagram http://img697.imageshack.us/img697/6713/diagramo.png
There is no point of making (2) asynchronous: you still would have to wait for web service to finish processing request. If you end HTTP request from browser to web application the client would have no clue what the result of request was.
It is much better to make asynchronous request from web browser to your web application. Ajax is ideal for that. In fact, that's what it was created for. Here's couple of links to get you started:
jQuery Ajax
ASP.NET AJAX
I'm trying to bind a datasource to a repeater, for instance, to a web service (.asmx from a different website) on page load. The webservice returns a DataSet from an sql call. What is the best way to go about doing this?
Because you're calling another website, you have to contend with two issues (especially if this web service is on somebody else's website or over the public internet). First, there might be a delay to retrieve the data from the other website. Second, the other website might timeout.
At a minimum you should consider an asychronous page request. As this MSDN article states:
If a synchronous request becomes I/O
bound—for example, if it calls out to
a remote Web service or queries a
remote database and waits for the call
to come back—then the thread assigned
to the request is stuck doing nothing
until the call returns. That impedes
scalability because the thread pool
has a finite number of threads
available. If all request-processing
threads are blocked waiting for I/O
operations to complete, additional
requests get queued up waiting for
threads to be free. At best,
throughput decreases because requests
wait longer to be processed. At worst,
the queue fills up and ASP.NET fails
subsequent requests with 503 "Server
Unavailable" errors.
But the best solution is probably to use AJAX. Load the page then make an ajax request to fill the repeater. That way you can have the nice "spinning" graphic or something else happening while you are waiting on the webservice.
Call the webservice, take the result, and bind it to your repeater.
If you can, you might also try to cache the information for a time on your side, if possible to help with overall performance.