Monday, March 17, 2008

Provide Status Updates for Long Running Operation Jobs - Part II

Following on from Part I that showed a simple way to give users some feedback on the progress status of long running jobs - here is the same code, this time running in an .aspx page. To run ASP.NET server side code you'll need to add a PageParserPath node to your web.config as covered here.

As before, make sure that your site collection includes a list named 'Long Running Operation Status' at the root web. This list is created when you install the Office SharePoint Server Publishing Infrastructure feature at the Site Collection Features level.


<%@ Page language="C#" MasterPageFile="~masterurl/default.master"    Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:progid="SharePoint.WebPartPage.Document" %>
<%@ Assembly Name="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.Publishing" %>
<%@ Import Namespace="Microsoft.SharePoint.Publishing.Internal" %>
<%@ Import Namespace="Microsoft.SharePoint.Utilities" %>
<script runat="server">
    const string PROGRESS_PAGE_URL = "/_layouts/LongRunningOperationProgress.aspx";

    public void StartJob(object sender, System.EventArgs e)
    {
        SPWeb web = SPContext.GetContext(this.Context).Web;
        LongRunningJob longRunningJob = new LongRunningJob();
        longRunningJob.Title = "Demo Long Running Job";
        longRunningJob.TotalOperationsToBePerformed = 15;
        longRunningJob.RedirectWhenFinished = true;
        longRunningJob.NavigateWhenDoneUrl = SPContext.GetContext(this.Context).List.RootFolder.ServerRelativeUrl;
        longRunningJob.Start(web);
        string url = string.Format("{0}{1}?JobId={2}", web.Url, PROGRESS_PAGE_URL, longRunningJob.JobId);
        SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context);
    }
    
    class LongRunningJob : LongRunningOperationJob
    {
        public override void DoWork()
        {
            for (this.OperationsPerformed = 0; this.OperationsPerformed < this.TotalOperationsToBePerformed; this.OperationsPerformed++)
            {
             //Do your work here
                this.StatusDescription = string.Format("im in ur long running job, doing ur work {0} of {1}...", this.OperationsPerformed, this.TotalOperationsToBePerformed);
                this.UpdateStatus();
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
</script>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<asp:Button runat="server" OnClick="StartJob" Text="Start Job" id="Button1"/>

</asp:Content>

6 comments:

Jorge said...

Hi again.
After the Long Running Operation Job it's taking to long to redirect. I even set the RedirectWhenFinished=false so that the user needs to click the OK button but it continues to take to long to redirect, about 30seconds to 1 minute.
Do you know why?
I'm using this LongRunningJob to create a MeetingWorkspace Site and some items on another List. The last thing I do on DoWork() method is this:

this.OperationsPerformed = this.TotalOperationsToBePerformed;
this.UpdateStatus();

Should I do anything else to make sure that the Long Running Operation is over?
Thanks a lot.

txs8311 said...

Hey - Take a look at the MillisecondsToWaitForFinish property - I haven't looked at how this works exactly, but it might be causing your delay.

Jorge said...

Thanks for your reply.
MillisecondsToWaitForFinish doesnt seem to work...After I create the site and the calendar's events I have to wait 1 minute and 15 seconds to be redirected.
This does not seem to be write! can it be because I may not be disposing all spsites and spwebs that I use in my code?
Thanks

mark said...

Hi,
I dont have the long running operation list despite activating the publishing feature!
Any ideas?

Thanks

txs8311 said...

Jorge - do you get a delay when you use the sample code above? If not, then it's probably something in the code you're running. If you're not able to step through the code, try running only half of it (comment out one half of the operations) - if it still runs slow, comment out half of that etc.

You could also take a look at how SharePoint uses the LongRunningOperationJob class, for example by using Reflector to open the Microsoft.SharePoint.Publishing.dll and viewing classes like Microsoft.SharePoint.Publishing.Internal.WebControls.MoveWebs etc.

txs8311 said...

Mark - the Long Running Operation Status list is hidden from browsers by default when activated. This means you won't be able to browse to it, but you should still be able to type the url directly into the browser, or see it using SharePoint Designer. If it's really not there - try activating the feature again, then check your SharePoint logs to see if anything shows up there (making sure you set the throttling appropriately low before you do so).