Skip to main content
added 2010 ootb method
Source Link
Rawling
  • 880
  • 2
  • 11
  • 25

Also, in SharePoint 2010 (and maybe before, for all I know) there's the SPStatefulLongOperation class. It's not very well documented, but here's an example of how I might be using it.

SPStatefulLongOperation.Begin(
    "Applying theme to sites.",
    "<span id='trailingSpan'></span>",
    (op) =>
    {
        op.Run((state) =>
        {
            foreach (SPWeb web in site.AllWebs)
            {
                state.Status =
                    "<script type='text/javascript'>" +
                     "document.all.item('trailingSpan').innerText = '" +
                     web.Title +
                     "';" + 
                     "</script>";
                selectedTheme.ApplyTo(web, true);
            }
        });

        op.End("ManageFeatures.aspx?Scope=Site");
    });

This works very similarly to the custom method above: every second, the value of state.Status is written to the Response (via HttpContext.Current) and flushed. Thus you want to be sending JavaScript updating your status element, rather than sending the current status. It's less efficient in that it sends the state even when it hasn't changed, but using the ootb code is a lot cleaner.


Also, in SharePoint 2010 (and maybe before, for all I know) there's the SPStatefulLongOperation class. It's not very well documented, but here's an example of how I might be using it.

SPStatefulLongOperation.Begin(
    "Applying theme to sites.",
    "<span id='trailingSpan'></span>",
    (op) =>
    {
        op.Run((state) =>
        {
            foreach (SPWeb web in site.AllWebs)
            {
                state.Status =
                    "<script type='text/javascript'>" +
                     "document.all.item('trailingSpan').innerText = '" +
                     web.Title +
                     "';" + 
                     "</script>";
                selectedTheme.ApplyTo(web, true);
            }
        });

        op.End("ManageFeatures.aspx?Scope=Site");
    });

This works very similarly to the custom method above: every second, the value of state.Status is written to the Response (via HttpContext.Current) and flushed. Thus you want to be sending JavaScript updating your status element, rather than sending the current status. It's less efficient in that it sends the state even when it hasn't changed, but using the ootb code is a lot cleaner.

Source Link
Rawling
  • 880
  • 2
  • 11
  • 25

The SPLongOperation class has two properties, LeadingHTML and TrailingHTML, that can be used to set two areas in the default Long Operation modal dialog when the job starts. Unfortunately, although you can change these properties while the job is in progress, the change isn't reflected in the dialog.

This blog post provides a custom SPLongOperation descendant that can make these changes appear on the dialog. Basically, how it works is:

  1. Wrap the initial LeadingHTML and TrailingHTML values in span elements with known IDs.
  2. When the user updates either property, push JavaScript to the client with Response.Write and Response.Flush that replaces the content of the relevant span with the new value.

(Aside: this class calls Write and Flush on the supplied Page parameter's Response property. Because I couldn't figure out what this Page should be, I wrote custom code instead of using the class and used HttpContext.Current.Response instead. This seemed to work, but my updates always seemed to be one update behind, so I had to put in a dummy Write and Flush after each real one.)

You should be able to use this for what you need - either directly use the supplied class in place of your operation, or take a look inside and emulate it yourself.