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
Related
I have an ASP.NET Webform which currently calls a Java WebService. The ASP.NET Webform is created/maintained inhouse, whereas the Java WS is a package solution where we only have a WS interface to the application.
The problem is, that the Java WS is sometimes slow to respond due to system load etc. and there is nothing I can do about this. So currently at the moment there is a long delay on the ASP.NET Webform sometimes if the Java-WS is slow to respond, sometimes causing ASP.NET to reach its timeout value and throw the connection.
I need to ensure data connectivity between these two applications, which I can do by increasing the timeout value, but I cannot have the ASP.NET form wait longer than a couple of seconds.
This is where the idea of a queuing system comes into place.
My idea is, to have the ASP.NET form build the soap request and then queue it in a local queue, where then a Daemon runs and fires off the requests at the Java-WS.
Before I start building something from scratch I need a couple of pointers.
Is my solution viable ?
Are there any libraries etc already out there that I can achieve this functionality with ?
Is there a better way of achieving what i am looking for ?
You can create a WindowsService hosting a WCF service.
Your web app can them call the WCF methods of your Windows Service.
Your windows service can call the java web service methods asynchronously, using the
begin/End pattern
Your windows service can even store the answers of the java web service, and expose them through another WCF methods. For example you could have this methods in your WCF service:
1) a method that allows to call inderectly a java web service and returnd an identifier for this call
2) another method that returns the java web service call result by presenting the identifier of the call
You can even use AJAX to call the WCF methods of your Windows Service.
You have two separate problems:
Your web form needs to learn to send a request to a service and later poll to get the results of that service. You can do this by writing a simple intermediate service (in WCF, please) which would have two operations: one to call the Java service asynchronously, and the other to find out whether the async call has completed, and return the results if it has.
You may need to persistently queue up requests to the Java service. The easiest way to do this, if performance isn't a top concern (and it seems not to be), is to break the intermediate service in #1 into two: one half calls the other half using a WCF MSMQ binding. This will transparently use MSMQ as a transport, causing queued requests to stay in the queue until they are pulled out by the second half. The second half would be written as a Windows service so that it comes up on system boot and starts emptying the queue.
you could use MSMQ for queuing up the requests from you client.
Bear in mind that MSMQ doesn't handle anything for you - it's just a transport.
All it does is take MSMQ messages and deliver them to MSMQ queues.
The creation of the original messages and the processing of the delivered messages is all handled in your own code on the sending and receiving machines: the destination machine would have to have MSMQ installed plus a custom service running to pick them up and process them
Anyway there is a librays for interop with MSQM using JAVA : http://msmqjava.codeplex.com/
Another way could be you can create a queue on one of your windows box and then create a service that pick up the messages form the Queue and foreward them to the Java service
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.
What is the difference between Web Services Asynchronous Call and Asynchronous Task's.
We are working an a ASP.NET application that requires to make a call to a Web Service Method that will process thousand rows of data. This process usually takes between 2 to 3 minutes (maybe more maybe less it depends of the amount of Data). So we run all the time in Timeout's on that specific page.
So we decided to go in rout of calling this Web Service Method Asynchronously, but we had a conflict caused by HTTP handler of one of the UI component's that we are using. Well lucky on that case we could remove the page from the httphandler directives.
So far no issues, but here it comes the question, a coworker find out that we can use instead of Asynchronous Webs Services Call, wrap a Synchronous call in a Asynchronous Task in the ASP.NET page and be able to keep the directives to the component, and execute the Web Service Method with out getting a Timeout.
So now my concern is what kind of issues we can find using Asynchronous Task's instead of an Asynchronous Call.
Thank you in advance.
Web services should not be used in this manner by the way. There's a reason HTTP timeouts are so low. You should have the Web service trigger the task either by setting a flag in the DB that an actual service picks up on or the web service should spawn a process.
If I understand your scenario, there should be no issues. In both cases, your page is asynchronous. In both cases, you don't wait for the service to complete - you give up the request thread while the service is running. In both cases, your page takes the same amount of time to execute as it would if you had called the service synchronously.
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.
Is it possible to use BackGroundWorker thread in ASP.NET 2.0 for the following scenario, so that the user at the browser's end does not have to wait for long time?
Scenario
The browser requests a page, say SendEmails.aspx
SendEmails.aspx page creates a BackgroundWorker thread, and supplies the thread with enough context to create and send emails.
The browser receives the response from the ComposeAndSendEmails.aspx, saying that emails are being sent.
Meanwhile, the background thread is engaged in a process of creating and sending emails which could take some considerable time to complete.
My main concern is about keeping the BackgroundWorker thread running, trying to send, say 50 emails while the ASP.NET workerprocess threadpool thread is long gone.
If you don't want to use the AJAX libraries, or the e-mail processing is REALLY long and would timeout a standard AJAX request, you can use an AsynchronousPostBack method that was the "old hack" in the .net 1.1 days.
Essentially what you do is have your submit button begin the e-mail processing in an asynchronous state, while the user is taken to an intermediate page. The benefit to this is that you can have your intermediate page refresh as much as needed, without worrying about hitting the standard timeouts.
When your background process is complete, it will put a little "done" flag in the database/application variable/whatever. When your intermediate page does a refresh of itself, it detects this flag and automatically redirects the user to the "done" page.
Again, AJAX makes all of this moot, but if for some reason you have a very intensive or timely process that has to be done over the web, this solution will work for you. I found a nice tutorial on it here and there are plenty more out there.
I had to use a process like this when we were working on a "web check-in" type application that was interfacing with a third party application and their import API was hideously slow.
EDIT: GAH! Curse you Guzlar and your god-like typing abilities 8^D.
You shouldn't do any threading from ASP.NET pages. Any thread that is long running is in danger of being killed when the worker process recycles. You can't predict when this will happen. Any long-running processes need to be handled by a windows service. You can kick off these processes by dropping a message in MSMQ, for example.
ThreadPool.QueueUserWorkItem(delegateThatSendsEmails)
or on System.Net.Mail.SmtpServer use the SendAsync method.
You want to put the email sending code on another thread, because then it will return the the user immediately, and will just process, no matter how long it takes.
It is possible. Once you start a new thread asynchronously from page, page request will proceed and send the page back to the user. The async thread will continue to run on the server but will no longer have access to the session.
If you have to show task progress, consider some Ajax techniques.
What you need to use for this scenario is Asynchronous Pages, a feature that was added in ASP.NET 2.0
Asynchronous pages offer a neat
solution to the problems caused by
I/O-bound requests. Page processing
begins on a thread-pool thread, but
that thread is returned to the thread
pool once an asynchronous I/O
operation begins in response to a
signal from ASP.NET. When the
operation completes, ASP.NET grabs
another thread from the thread pool
and finishes processing the request.
Scalability increases because
thread-pool threads are used more
efficiently. Threads that would
otherwise be stuck waiting for I/O to
complete can now be used to service
other requests. The direct
beneficiaries are requests that don't
perform lengthy I/O operations and can
therefore get in and out of the
pipeline quickly. Long waits to get
into the pipeline have a
disproportionately negative impact on
the performance of such requests.
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
If you want using multitheading in your ASP page, you might using simple threading model like this:
{
System.Threading.Thread _thread = new Thread(new ThreadStart(Activity_DoWork));
_thred.Start();
}
Activity_DoWork()
{
/*Do some things...
}
This method is correct working with ASP pages. The ASP page with BackgroundWorker will not start while BackgroundWorker will finish.
5 years later, but problems the same… If you want to perform fire-and-forget operations from your application and forget about all difficulties related to background job processing in ASP.NET applications, you can use http://hangfire.io.
It does not loose your jobs on recycling process, because it uses persistent storage to keep information about background jobs.
It automatically retries your background jobs that were aborted or failed due to transient exception (SMTP Server connectivity errors).
It allows you to easily debug background jobs through the integrated web interface.
It is very easy to install/configure/use HangFire.
There is also tutorial Sending Mail in Background with ASP.NET MVC for using HangFire with Postal.