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:
- Wrap the initial
LeadingHTML
and TrailingHTML
values in span
elements with known IDs.
- 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.
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.