Concurrent asynchronous callbacks - c#

Question to die hard asp.net experts. I have spent much time trying to find an answer or to do it myself but no luck so far.
ASP.NET web application. I plan to improve page load time so that user experience is better. I want to delay load sections of page using UpdatePanels. I can make one UpdatePanel update itself right after page loads using timer with minimum interval. That works just fine but steps begin when trying to have it done with multiple UpdatePanels. Basically what happens is all panels are updated but sequentially rather than all at the same time.
Now, I have read that this is due to a fact that each async postback result caries full page viewstate and to prevent from viewstate inconsistencies asynchronous postbacks are serialized. Actually they say that only last callback would be successful so I am lucky to have them serialized, I guess.
And now the big question: has anyone found a way round it? In ASP.NET if possible. This would be a VERY valued answer probably not only for me.
Thanks, thanks, thanks (for working answer :-)

UpdatePanels are synchronous by design.
If you want to execute multiple requests concurrently, you'll need to use page methods, AJAX services, or raw AJAX. Either way means giving up on ViewState.
If you want to render ASP.Net controls concurrently for multiple AJAX requests, you can make small independent ASPX files that contain the controls, send AJAX requests to them, and insert the rendered HTML into the DOM. In jQuery, you would do this like this: $('selector').load('something.aspx'). Note that neither postbacks nor viewstate would work.

Related

Setting session variable causes slowness in FileContentResult rendering in MVC

Here's my predicament. I have a page in an MVC app that's displaying a list of search results via a partial view using an ajax call. The model is a List<List<string>> representing a dynamic data set, i.e., the users choose which columns they want returned and what order they come back in. All the view is doing is a nested loop which builds out the results table.
One of the potential returned fields is an image of a barcode which is being rendered by another method returning a FileContentResult. Normally this works great, it's slick and performant, to the point where I don't really notice all of the barcodes being rendered and downloaded at all, even in a data set that's hundreds of rows long.
The problem arises when I set a session variable using HttpContext.Current.Session, even something as simple as Session["thingy"] = "thingy";. When that happens there is a drastic performance hit with the barcode images. Result sets that would take a second to load fully are now suffering from image "pop in" for up to 10 seconds after the search button is hit. A few times an image has failed to load, giving an error to the effect of "the server is too busy right now".
Does anyone out there in overflowland have any insight into what could be causing this behavior? I've found a kludgy workaround but it involves unnecessary ajax calls and extra trips to the database.
So the issue was that IIS was treating requests synchronously whenever there was anything stored in the session. So all of my calls to the barcode action were waiting until the last one had finished before moving on, hence the pop-in.
The answer was in this link posted by Alexei. Oddly enough it was the most downvoted answer that provided the easiest solution. I created a new controller for my images and refactored the barcode rendering action into it, then decorated the controller with [SessionState(SessionStateBehavior.Disabled)], forcing IIS to treat any requests to the actions in the controller as asynchronous.
I was having the same issues a while ago. Fixed it by setting EnableSessionState to ReadOnly in my web.config.
I thought it might have some negative side effects but none so far. Even posted a question here in SO looking for comments.
See here: EnableSessionState = ReadOnly - possible side effects?

Update progress bar from codebehind

I have a really long submit()-type function on one of my web pages that runs entirely on the server, and I'd like to display a progress bar to the client to show the, well, progress.
I'd be ok with updating it at intervals of like 20% so long as I can show them something.
Is this even possible? Maybe some kind of control with runat="server"? I'm kind of lost for ideas here.
It's possible, but it's quite a bit harder to do in a web based environment than in, for example, a desktop based environment.
What you'll have to do is submit a request to the server, have the server start the async task and then send a response back to the client. The client will then need to periodically poll the server (likely/ideally using AJAX) for updates. The server will want to, within the long running task's body, set a Session value (or use some other method of storing state) that can be accessed by the client's polling method.
It's nasty, and messy, and inefficient, so you wouldn't want to do this if there are going to be lots of users executing this.
Here is an example implementation by Microsoft. Note that this example uses UpdatePanel objects, ASP timers, etc. which make the code quite a bit simpler to write (and it's still not all that pretty) but these components are fairly "heavy". Using explicity AJAX calls, creating web methods rather than doing full postbacks, etc. will improve the performance quite a bit. As I said though, even in the best of cases, it's a performance nightmare. Don't do this if you have a lot of users or if this is an operation performed very much. If it's just for occasional use by a small percentage of admin users then that may not be a concern, and it does add a lot from the user's perspective.
I would take a look at .net 4.5's async and await.
Using Asynchronous Methods in ASP.NET MVC 4 -- (MVC example I know sorry)
Then check out this example using a progress bar

WCF GridView paging and caching

Is there a way to cache a user requested data depending upon the user/connection. My situation is that I display the data returned from the WCF in ASP.NET Gridview using paging. The gridview paging displays only 10 items at a time. Whenever the next page is clicked, the service is getting called again (which takes time). After each call the WCF connection is closed. Is there a way to fix this issue? I read upon WCF ASP.NET caching mechanism that caches functions call data and it expires after a certain time. My main thing, is per user/call caching like return 10 items at a time without calling the long running function again for each 10 sets of data. Is there a way to do?
Basically call the function the first time and get 100 items, and return it 10 at a time, without ever running the function again (which gets 100 items)?
I believe that the ASP.NET Gridview always does a postback which result in function call everytime a user changes page. But I maybe proven wrong by someone.
That being said, this may not be the best solution for you. But you could avoid using ASP.NET Gridview in your scenario. When you run a WCF call and return 100 items, you keep them on client side as a JSON file stored in memory, then use jQuery or some other form of javascript to enable users to go through pages without making another function call.
Edited
This may prove useful to you to help you do paging on client-side without having multiple repeated call to the server
http://www.smallworkarounds.net/2009/02/jquery-aspnet-how-to-implement.html

Fire a method execution after x seconds in code behind - ASP.NET/C#

After x seconds, after the page loads, I need to execute a method in the code behind. I cannot move this logic into JS.
Do I need to use delegates/events for this? Can anyone give me an example (preferably with a code snippet)??
Put a counter in JS that measures the X seconds. Once it's reached it's mark, have it send a message via AJAX back to the server, and the server executes the method.
That's about the only way to ensure that the counting of those seconds is accurate to when the page finishes loading. If you don't care too much about accuracy, just have the server kick off the method x seconds after it sends the page.
Your best solution is going to be to use javascript to either cause a postback, or to send an AJAX request to the server after the X seconds has elapsed.
Due to the page lifecycle of ASP.NET pages, you can't do it from the code-behind directly. You can see this article for more information on the ASP.NET Page Lifecycle.
I would put a bit of javascript that uses the "SetTimeout" to trigger a JS method call that either does the Ajax request, or forces the postback, depending on what you are doing.
Edit
Based on the additional information you put in the comments to the post i would recommend a modified approach. If all you are doing is launching another window, and you want to delay that logic.
Instead of directly calling the window.open or however you are doing it. Simply put that code inside of the code that would be called using the "SetTimeout" method as I referred to earlier. No need to involve the server-side at all.

Set ASP.net executionTimeout in code / "refresh" request

I'll have an ASP.net page that creates some Excel Sheets and sends them to the user. The problem is, sometimes I get Http timeouts, presumably because the Request runs longer than executionTimeout (110 seconds per default).
I just wonder what my options are to prevent this, without wanting to generally increase the executionTimeout in web.config?
In PHP, set_time_limit exists which can be used in a function to extend its life, but I did not see anything like that in C#/ASP.net?
How do you handle long-running functions in ASP.net?
If you want to increase the execution timeout for this one request you can set
HttpContext.Current.Server.ScriptTimeout
But you still may have the problem of the client timing out which you can't reliably solve directly from the server. To get around that you could implement a "processing" page (like Rob suggests) that posts back until the response is ready. Or you might want to look into AJAX to do something similar.
I've not really had to face this issue too much yet myself, so please keep that in mind.
Is there not anyway you can run the process async and specify a callback method to occur once complete, and then keep the page in a "we are processing your request.." loop cycle. You could then open this up to add some nice UI enhancements as well.
Just kinda thinking out loud. That would probably be the sort of thing I would like to do :)

Categories