6

I have a page that performs a long-running task (10 to 15 seconds) in the page_load method.

I have client-side javascript code that will display a decent "page loading" animated gif to the user.

I am able to invoke the JavaScript method from the code-behind, to display the "page loading" animated gif, however, the long-running task is hanging up the UI such that the animated gif doesn't actually display until after the long-running task is complete, which is the exact opposite of what I want.

To test this out, in my page_load method I make a call to the JavaScript method to display the animated gif. Then, I use Thread.Sleep(10000). What happens is that the animated gif doesn't display until after Thread.Sleep is complete.

Obviously I am doing something incorrect.

Any advice would be appreciated.

Thanks.

Chris

Below is an example of the code-behind:

protected void Page_Load(object sender, EventArgs e)
    {
        ClientScript.RegisterStartupScript
              (GetType(), "Javascript", "javascript: ShowWaitIndicator(); ", true);

        Response.Flush();

        Thread.Sleep(10000);
    }
1
  • You can't invoke javascript from code-behind. All you can do is add it to the response stream, which is what ClientScript.RegisterStartupScript is doing. This will eventually get sent back to the browser. It's two completely different contexts. Codebehind runs on the server, javascript executes on the browser. Commented Jun 10, 2010 at 18:23

6 Answers 6

4

I accomplished this by placing a timer on the page. After its first tick disable it and run your task.

<asp:Timer runat="server" id="UpdateTimer" interval="500" ontick="UpdateTimer_Tick" />

I placed this within an UpdatePanel for my needs. I'm not sure what will work best for you. Then in your code behind...

Protected Sub UpdateTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        UpdateTimer.Enabled = False

        ' run method here

    End Sub
Sign up to request clarification or add additional context in comments.

Comments

4

The reason is that the Page.Load event fires before any response has been sent to the client; so any instructions for the client (such as executing your javascript) doesn't occur until the client receives the response.

So... placing the long-running task in Page.Load won't have the effect you want. This sounds like a case for using AJAX or some other form of asynchronous data-retrieval. In this scenario the page you return to the client doesn't containt he result of your long-running task--so the page itself (with it's spinner) loads quickly, then the client requests the data; when the data is ready (10-15 seconds later) you can update the DOM in the client with the results.

Comments

4

Following example will work for you. just place in Page Load Event.

  Response.Write("<div id=\"loading\" style=\"position:absolute; width:100%; text-align:center; top:300px;\"><img src=\"http://www.cse.iitk.ac.in/users/singhroh/images/loading.gif\" border=0></div>");
  Response.Flush();
  System.Threading.Thread.Sleep(5000);        
  Response.Write("script>document.getElementById('loading').style.display='none';</script>");

1 Comment

Had the same idea seems it requires you to add Buffer="false" to the top directive of the page else it just displays all at once.
1

I would avoid invoking your JavaScript from the code-behind.

Instead, utilize the jQuery library. You can trigger your code to be called immediately after the DOM is loaded by using the following code:

$(document).ready(function() {
     //Call your JavaScript method here.
});

You'll also need to add jQuery to your page, which is a single script include from the Microsoft CDN. Add this to your markup to do this:

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js"></script>

This will call your GIF JavaScript method immediately when the page is loaded and you can eliminate your Thread.Sleep. I'm assuming your animated GIF method automatically hides the image after 10-15 seconds.

2 Comments

I am only using Thread.Sleep to simulate a long running task. I tried your approach, and put Thread.Sleep(10000) in the page_load method and it still doesn't load the gif until after the 10 seconds.
Gotcha, I thought you were using the Thread.Sleep to delay the disappearance of the GIF. In that case, Yoooder's response is the best path to go down. You can still use jQuery and utilize the ".ajax" method to call a page method decorated with the "WebMethod" attribute. There's an article about it here: encosia.com/2008/05/29/… Your webmethod would contain your Thread.Sleep to simulate the long running task.
1

Taking it old school, you could switch buffering off. With buffering on (the default), the page is generated in it's entirity before it's sent to the client. If you switch buffering off, it's sent as it's loaded, so you can send the html to switch the loading graphic on, do your long running task, then send some javascript to switch it off.

Comments

0

It sounds like the Javascript onload is being displayed after the ASP onload processes. You may want to delay your time-intensive action to Page.LoadComplete - this way, your user will see the Javascript render before the intensive operation occurs.

Then, you would update the page contents as needed after the function completes.

Can you provide an example of the code?

1 Comment

I modified the original post to include an example of the code-behind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.