Let's say I would like to change the text of an element, during some long function in a script:
// Inside test.aspx.cs
void SomeLongFunction_CalledOnClick()
{
this.idOfElement.Text = "something";
}
When, precisely, is the client sent information about this update? Can I force it to happen earlier?
If you are using web forms, the content of the browser is updated when the "Render" stage of the page life cycle runs. Generally the code in a web form's code behind runs before the render stage.
Here is a link that explains the page lifecycle
I'm afraid that if you are looking to update the UI to indicate progress, the web forms model isn't made to work that way. All the content is sent to the browser as a single unit during the render phase.
If you want your UI to show progress you could poll for updates using ajax calls, or use a technology like SignalR (although it's probably overkill for your use case).
Related
After reading Dianyang Wu article and this excellent post I managed to build a small .net app (almost a C&P from Wu source code) to automatize tests (let's call it protoTestApp). My final goal is to open a dozen small windows and in each simulate a different user interacting with a web app to stress it.
It works for some extend but after I logon on the web app (let's call it InternalTestSubject) it calls a external url (let's call it ExternalTestSubject) and injects it's content on a iFrame. This particular external url is another web app and it ill look up for the parent window to get some parameters. Opening ExternalTestSubject directly is not a option.
My problem is at my protoTestApp I want to also interact with that ExternalTestSubject (find a button by id, click it, etc) but at my CompletedEvent handler the iFrame is still empty.
The WebBrowser shows both web apps full loaded and working, so I suppose the handler is just not waiting for the iFrame content to load since it's done by a Ajax async call.
Any advice to acomplish it?
I think I explained this in the answer you linked (and in more details in another related answer). AJAX pages are non-determinustic, so there is no generic approach.
Use periodic asynchronous polling to watch the page's current HTML snapshot or DOM for changes, the linked post illustrates how to do that. You can poll the frame's content in the same way.
I can imagine the frame reports to be ready but it actually does not. For instance, the frame contains frames, you have no way to know whether all these frames are loaded by using DocumentCompleted event.
In short: Using a frame to load external stuff and do the testing is not a good approach. Even if you use a timer to check the loading status manually. But according to security considerations, you will have many problems to access the DOM.
I have two suggestions for you:
Create a WebBrowser instance and open external test subject into it. You will have a very good chance to know, whether document (and its frames) have been loaded completely. You still have the full control to access any elements of the WebBrowser or cookies or click elements or change elements.
Use 3rd tool such as Selenium as test driver.
Update 1:
As the questioner does not want any 3rd tool, I'd suggest let the internal test subject query the loading completeness of the target frame periodically. Possible code can be check document.readyState == 'complete'.
So far as I know, as the external test subject is embedded as frame, due to security consideration, you might not able to access the DOM of the frame. In other words, you cannot do mouse clicks, etc., unless you change the security settings for the Webbrowser control first.
How can I show some type of message in my ASPX web page ( I'm using WebForms, not MVC ), which represents as a "wait process" while some method of my project is executing.
I'm not asking about how to make some HTML/CSS/DOM stuff, I'm asking more about asynchronous check.
For e.g.: some data from web could be delivered to client not quickly and when it does occur - it looks very ugly for the user. It's just idling and looks like a page with bug, where there is no well highlighted status ( many users don't watch in browsers the page loading states, they want to look it in web applications exactly, like in desktop applications ).
I want to show a message like "waiting for the operation end"
and I don't know how to make an asynchronous check in my ASPX page for getting the current state when some methods execute ( are they finished or not etc... ).
What I really want looks like in pseudo-code:
while (methodExecuting) show(waitMessage);
How could it be done in WebForms of ASP.NET project?
I suggest you use a "progressBar" indicating your condition periodically.
Here is a good link explaining step by step how to use it.
Asynchronous processing in ASP.Net with Ajax progress bar
You can download this solution at the following: http://weblogs.asp.net/blogs/seanmcalinden/Solutions/AjaxProgressBarExample.zip
I would have done it with JQuery UI Progress Bar.
Change your C# function to webmethod and then call it with jquery. here is the tutorial for you. Call the webmethod and enable the progress bar, when it is completed disable the progress bar.
hope it helps.
I'm quite new to asp.net and C# so bear with me. Also my apologies if this have been asked before... if so please direct me to a page which is of help.
What I have:
A page: With 4 updatepanels
1st UpdatePanel which contains a (item) gridview, user display options (not important to this question) and button which perform a database search which returns a list of items displayed to the grid. User selects an item on this grid...
2nd UpdatePanel contains a dropdownlist containing a list of available task loaded from an XML. User will select a task, which displays a bunch of available options/parameters (also loaded from XML file) to another (parameter) gridview in 2nd updatepanel. Gridview here will always have one row of data. I'm using gridview here because it is easier rather than creating dynamic controls (paramaters are different to each task ). User is able to enter parameter values into the grid. User clicks on an Add button and the the task is added to another gridview in the 3rd updatepanel.
3rd UpdatePanel contains a (task) gridview which contains all the task added by user. There's also a button which is suppose to batch run all the task. When the button is clicked, it goes through the (task) gridview looking for pending task to run. For each pending task, it calls a web service which handles the task appropriately. Web service returns the task result together with log output.
4th UpdatedPanel for now just contains a div that displays the log output returned from web service.
What I want to further work on and not know how is:
how do I perform an 'asynchronous' batch job? What i'm trying to achieve is that, when user clicks on the batch run button, the 3rd (task) updatepanel together with all it's control get disabled while the batch jobs run 'behind the scene'. Depending on the task, each task could take up to 5seconds each. If user had created 60 tasks, I would think this will also cause the page to timeout?
While the batch job is running, user can further search for other items in (item) UpdatePanel and add new tasks using (parameter) updatepanel to (task) updatepanel.
(Task) UpdatePanel will be showing a 'Job in progress...' overlay of some sort when job is running.
Hope you understand my question. Much appreciated if someone could be kind enough to give some guidance and/or directions on how to tackle this task
Further info:
Using Framework 3.5
Using Asp.net C# + Ajax
Web Service is of gSoap on a solaris box
Many thanks in advance.
Sorry for being a noob, i was trying to reply to your help but found that there's a limited of characters i can put in. I'll just update my own comments for now.
Thanks for your suggestion. Sorry for the late response, I've been looking around the other day and had made some changes, getting it to work with 'PageAsyncTask' and 'IAsyncResult'. I've created a web service class which will be called by the page. The new web service class will than called the gSoap web service. I've managed to some sort of running it 'asynchronously'.
I have a button which executes:
protected void StartASyncJob()
{
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncCommandTask),
new EndEventHandler(EndAsyncCommandTask),
new EndEventHandler(AsyncCommandTaskTimeOut), null);
RegisterAsyncTask(task);
}
BeginAsyncCommandTask will go through the grid, get the first pending task and calls the web service.
EndAsyncCommandTask will then retrieve the return results, writes out the (log) UpdatePanel. It will then execute StartASyncJob() again looking for the next pending record to process.
All this works ONLY if don't do anything else on the page.
If I was (while the asynchronous process was running ) to do a search for more items in (item) gridview or select a new task from
(task) dropdownlist, the event will not fire till the asynchronous web service process has completed. And when it's completed, the dropdownlist or search event fires, my log details returned from the web service is not updated.
I guess the 'wait' is caused by 'PageAsyncTask' being 'spawn' from the same page thread?
I would have thought having the 'asynchronous' web service will enable the user to do more than one thing at a time giving better user experience. But it seems I'm wrong and/or have not done it right.
I have not tried your suggestion of using QueueUserWorkItem; but before I do, may i ask if it will give the same effect as using 'PageAsyncTask'. Will using QueueUserWorkItem has the same effect of 'spawning from same page thread' ?
Many thanks in advance. Sorry if i've not explained myself well and please do let me know if you need me to post my code.
there are a few solutions, but depends on how much control you have on the server.
If you have full access control to server, you may create a separate application which will take care of the Tasks; the application can be a Windows Service, and the communication between your page and the application would be either a database or MSMMQ (the communication mainly means the list of the Tasks and their states - 1. to be executed, 2. executing 3. finished).
Another solution is in case you don't have full access control to server, but it will require to implement some communication between threads. Instead of having the application I described at point 1. you can have a separate thread, which can be started this way:
System.Threading.ThreadPool.QueueUserWorkItem(foo => LauchTaskRunner());
Suppose you implemented a method called LaunchTaskRunner which in a loop just processes the list of existing Tasks, the above line will start it into a separate process. You can communicate with this method (which is running in a separate thread) through some static variable (declared in the page), e.g.:
public class YourPage : System.Web.UI.Page{
static IList<Task> tasks;
static void LauchTaskRunner(){
// here make use of tasks variable
}
}
Everytime the (tasks)updatepanel gets refreshed, it should render based on tasks variable.
Is there any mechanism that I can push data into a webbrowser control from the containing windows forms application. Specifically the webbrowser control contains some knockout.js and I want to allow some external events such as changes to certain files in the local filesystem to update the knockout viewModel.
At the moment I have this working after a fashion with the JS in the webbrowser control issuing a longpolling jsonp requests to a micro webserver I have written running in the windows forms application (note that this is not the place that the web page itself is server from hence jsonp. Also, the micro webserver is basically just a httpListner). When the forms app receives a file change event it returns a response via the micro webserver and that updates the knockout viewmodel.
The problem is this all feels fragile - if the file events come thick and fast they can start being skipped - it looks like my micro webserver is trying to return multiple results to the same stream. I can fix that, but overall its looking nasty and fragile.
The question is: am I missing any much simpler way to have the containing application signal something (i.e. pass some JSON) to the web page running in a webbrowsercontrol (without a page refresh!)
You could create an element, say a div with an id
<div id='external-json' data-bind='jsonHandler : {}' style='display:none'></div>
Then write json to this div from within your winforms app..
var myJson = "{test : 1}";
this.browser.Document.Body.GetElementById("external-json").innerText = myJson;
You could even create a knockout custom binding to react to this
ko.bindingHandlers.jsonHandler = {
update: function(element, valueAccessor) {
//do something with the json
var json = element.innerText;
var obj = eval(json); //hmm
alert(obj.test);
}
};
This is obviously a simple example and you could probably improve the idea a lot, you may need a queue of messages, possibly calling a function in your client script instead of using the element.
We have a problem with many of our website written C# ASP.NET.
The problem is that often a C# page will never fully load from the server.
The page content itself load fine but Images but more annoying Scripts (Javascript) seam to hang and never come down and depending on the content it might lock up the page on Ajax Postback.
This problem is not limited to a single server as it happens on development machines as well as pre production and production servers.
The development machine are just using the inbuilt VS IIS Instance.
All pages that have this problem use ASP.NET Update Panels with varying versions of AJAX Toolkit.
Thanks
One of the possible reasons is that your postbacks are being triggered on some events which are either being fired continuously. Another possible cause is that the page life cycle is not getting completed (e.g. infinite loop). If you can post some code, you would get precise answers.
Thanks,
Vamyip
Try using asp.net trace to see which page event is taking longer. Also try using fiddler from client side to see the real traffic and error codes. If you share the fiddler logs I may be able to tell more about what's happening.
You can check the time used by all the resourced that are loaded on the page using Firefox and firebug add-on
Anyway the updatepanel doesn't work very well with heavy pages : it posts the whole page to the server and get the whole rendered HTML even if you need refresh a small portion of the page.
if you can you should replace the updatepanel with async Jquery call to the get the the response as JSON and then populate the page as you wish or try to use anothe approach similar to the update panel.
have a look at:
http://www.codeproject.com/KB/aspnet/partialRendering.aspx