I have MVC application (applies to non MVC as well) where a user is posting in data. I need to take this data, send it off to two seperate end points (one using a WebRequest form POST and one using a Web Service), parse the result, and send the result back to the original user.
The issue at hand is that both end points take about 20-30 seconds to respond (response is a string) which means that I should probably execute these two calls asynchronously. At the same time I want to wait to respond to the original user until I get both results back. I am guessing I might have to use some sort of object lock so the response does not get sent back before the two calls are complete?
Am I on the right path? Does anyone have any information on how to achieve this? Any help is appreciated.
Thanks
EDIT
Based on the responses I decided to go with async controllers since I am already working with a MVC application. Thank you for your input.
You can invoke Join on the two asynchronous threads to wait for their return. You'll also want to look into asynchronous controllers. This is available in MVC2 but you can also look at the MVC1 features I believe to implement asynchronous actions. You'll want to do this so you're not blocking IIS from processing more threads.
I think you'll find this helpful: Rx: Piecing together multiple IObservable web requests
In particular, using ForkJoin to wait until both responses come back as mentioned in the comments:
Also bonus question, there is a case where I would like to execute web calls simultaneously
and when all are finished execute another observable which will until other calls are finished.
Use Observable.ForkJoin to execute
multiple async calls simultaneously
and then join all of the results into
a single IObservable. Then use
SelectMany (another from statement)
just like above, to subscribe to
another observable based on the joined
result.
Related
I've created web application that has a sub that builds a contacts list. This sub fetches phone numbers and email address from a contacts db based on ids that are provided by a user. At it's fastest, the application will process about four ids per second. With 200-300 ids at any given time, the completion time is long.
Time is not really the problem, it's end user status updates. I've created a very crude web service that reads the "CurrentRecordNumber" that is stored in a session variable as the app loops through the ids. I intend to use javascript to call the webmethod from the app periodically to update status.
My problem is that when debugging, the webmethod call will complete successfully, but not until the app is finished processing.
This seems like a very simple problem. I must not be using the right terms because my results seem overly complicated.
I'm very new to asynchronous features of ASP.NET so please forgive. I have, however, written some Winforms that incorporate multiple threads so I have a basic understanding of threading.
This is due to the way ASP.NET treats session. You haven't said whether you are using webforms or MVC, but MVC has a quick workaround for this.
First, the problem:
SessionState is designed to be accessed by one request at a time, in the order received by the server. Think of this as a queue at the bank with only one bank teller available. The first person in line is the first to be helped (though this is on a per-session basis, not a per-user).
ASP.NET locks all other requests that require SessionState from executing until the previous one is done.
I haven't tried to correct this problem in web forms, but the easiest way I know of would be to not require SessionState on your progress check.
In MVC, there's a SessionState attribute that can be applied to the controller or method, indicating that there's no chance of a call to that method overwriting SessionState. As long as your call is read-only, you can make your controller code use this attribute to allow multiple async requests simultaneously:
<SessionState(SessionStateBehavior.ReadOnly)>
Public Class MyController
I have a program in which it insert a raw in a table after certain operations. I wan to call a web service in code behind to do some special tasks by the using of info that there is in the inserted row.
How I can do that?
Is it good idea to invoke this web service from a stored procedure or not? What are the other options?
More Details: Actually, I have an operation in my web application that take a long time to be completed and it is seriously time consuming operation. I don't want client wait until this process finish. That is why I decide write a web service to do this process in the background.
Therefore, I think it may be a good idea that when client request receive I insert his request in a table and call a web service to handle it. Moreover, I do not want to wait until web service return the result, so I will aware client from its result through the report. I do not know what is the best solution to handle it.
I usually keep myself far away from table triggers(it sounds like you're about to use an on insert trigger for a table).
I don't know your specific situation but you could either :
Call the webservice before or after you call the stored procedure, this way the data layer(stored proc) only handles data and nothing more. You're logical layer will handle the logic of calling an extra webservice.
Write a service that will periodicly read a table and notify the webservice of the latest modifications. More messy but it resembles more the effect you're trying to achieve.
There are probably more solutions but i'd need more information on what it exactly is you're doing. Right now it's kinda vague :)
It is never a good idea to call webservice from Stored procs or other DB objects. You can call it from your code, just after you execute the insert and commit it.
The problem it sounds like is that you cannot guarantee that the web service will be called unless you call it before committing the transaction. However, it sounds like the web service needs to be called after commit. In this case, it sounds like you should use a message queue. You could either build one in your database or you could use one off the shelf (http://aws.amazon.com/sqs/ or http://www.windowsazure.com/en-us/home/features/messaging/).
The steps would be:
Insert message into queue (after this is success you can return the call, depending on what your contract with the caller is)
Read message
Insert into table
Call web service
Delete message
The downside is that you will need to make the operations (inserting into the table and calling the web service) idempotent.
Is it possible to cache a page render on an iis web server, but still receive and write query string values (that don't affect output) to the database? So that the page render does not have to wait for the database trip to execute in order to serve the page? If possible, how do I implement?
For example, we track various affiliate and search marketing data via query strings, and in the master page code behind, we write the given query string data to the database. The output of the page doesn't change at all for the user (however we may set a cookie based off the qs parameter).
My understanding is that the page render has to wait for the database trip to fully execute in order to render the page. Is that even true?
Yes in general though it can depend on how one handles the caching.
First, you should move that tracking stuff to where it belongs -- a HttpModule. Page need not concern itself. Second, what you probably want to look into is some sort of fire and forget service call or message queueing. This makes the database write a non-blocking operation rather than a blocking operation.
Some options for making the operation non-blocking:
if you are actually writing to a web service, there is an underappreciated [OperationContract(IsOneWay = true)] decoration. Tells the generated proxy to fire and forget the call, will not wait for a response.
Another option would be to use the Asynchronous ADO.NET bits, especially BeginExecuteNonQuery. If you don't handle the callback this should just execute off your thread.
You could always just spawn a thread and deal with it in a non-blocking manner yourself. Just be real careful about handling errors on this thread -- unhandled exceptions will take out the app domain.
Using a Generic Handler, I'd like to 2 do things in parallel. First, I need to send a request to a 3rd part and get the result back (this can take up to 25 seconds) and while that is happening, parse some XML and insert a record into a database.
How would I go about issuing an Http request (like GetResponse()) but not have it pause until it gets a response?
Create an asynchronous HTTP handler class. In your BeginProcessRequest, you can create two tasks, one for the 3rd party request, one for the XML parse and then run them in parallel. Here's a pretty good tutorial that shows how to define tasks that return values and run them in parallel.
Another option is creating a web service class in your project and having the web service do the work for the 3rd party request. Methods in a web service can be called asynchronously, so you can create a method in the service, reference the service from your page, then use the asynchronous overload of the method.
in this sample, two threads created; a worker thread created by BeginInvoke and an I/O completion thread created by SendAsync method.
but another author in his UnsafeQueueNativeOverlapped example, don't recommend this.
i want to use SendAsync or ...Async in an asp.net page and i want to use PageAsyncTask.
however, its BeginEventHandler requires AsyncResult to be returned which SendAsync does not return.
afaik, event based async pattern is the most recommended way so how could we call SendAsync or any ...Async methods without creating two threads and hurting the performance?
Actually if you used the beginIvoke and endInvoke for delegates or ThreadPool.WorkerItem it will not make any difference in your application because they are using the same thread that asp.net uses throw the iis
so now you have only 2 solution to make async calls first u will write your own threading classes (but be careful )
second use the PageAsyncTasks(recommended) this one much more safe and it's designed to work perfectly with asp.net
it's not about hurting the performance as much as it's about how and when to use asnyc tasks
if your process really take much time until it finish (because IIS will wait until all processes finish even the asnyc ones then start rendering) then you have to go to async solution instead it will make a draw back in performance
Note:
there is a difference between AddOnPreRenderCompleteAsync and RegisterAsyncTask
in there implementation they look the same but in the second one
you have access to the current http
context ,impersonation, culture and
profile data etc
you can run many tasks in parallel
you have timeout event and you can
determine timeout in the page
attribute
you can call RegisterAsyncTask
several times in one request to
register several async operations