Showing posts with label Progress Page. Show all posts
Showing posts with label Progress Page. Show all posts

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>

Monday, November 5, 2007

Provide Status Updates for Long Running Operation Jobs

A simple way to give users some feedback on the progress status of long running jobs is provided by the Microsoft.SharePoint.Publishing assembly. When a class that inherits from the LongRunningOperationJob class has its start method invoked, a list item is added to the Long Running Operation Status list in the root web. Providing a link to the LongRunningOperationProgress.aspx page along with the guid of this list item will display an update page with a progress bar similar to that shown below:

Long Running Job Status Page

A LongRunningOperationJob might not necessary be designed to run as a SPJobDefinition timer job, although there's no reason you couldn't combine the two to provide more granular information than the _admin/ServiceRunningJobs.aspx page provides.

Some example code follows. Before running it, 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. The list apparently isn't removed when this feature is uninstalled so it's not necessary to have the Publishing Infrastructure feature activated if you don't want it to be - just activate then deactivate it.

The Microsoft.SharePoint.Publishing assembly can be found here:
%Program Files%\Microsoft Office Servers\12.0\Bin\Microsoft.SharePoint.Publishing.dll

using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Publishing.Internal;
 
namespace DevHoleDemo
{
    class Program
    {
        const string STATUS_LIST_NAME = "Long Running Operation Status";
        const string PROGRESS_PAGE_URL = "/_layouts/LongRunningOperationProgress.aspx";
        static void Main(string[] args)
        {
            string webURL = "http://localhost/";
            using (SPSite site = new SPSite(webURL))
            {
                using (SPWeb web = site.RootWeb)
                {
                    LongRunningJob longRunningJob = new LongRunningJob();
                    longRunningJob.Title = "Demo Long Running Job";
                    longRunningJob.TotalOperationsToBePerformed = 30;
                    longRunningJob.RedirectWhenFinished = true;
                    longRunningJob.NavigateWhenDoneUrl = web.Url + "/" + STATUS_LIST_NAME;
                    longRunningJob.Start(web);
                    Process.Start("iexplore.exe", string.Format("{0}{1}?JobId={2}", web.Url, PROGRESS_PAGE_URL, longRunningJob.JobId));
                    LongRunningOperationStatus jobStatus;
                    do
                    {
                        jobStatus = LongRunningOperationStatus.GetJob(site, longRunningJob.JobId);
                        Console.WriteLine(jobStatus.StatusDescription);
                        Thread.Sleep(1000);
                    } while (jobStatus.Status != LongRunningOperationJob.OperationStatus.Successful);
                }
            }
        }
    }
 
    class LongRunningJob : LongRunningOperationJob
    {
        public override void DoWork()
        {
            for (this.OperationsPerformed = 0; this.OperationsPerformed < this.TotalOperationsToBePerformed; this.OperationsPerformed++)
            {
                this.StatusDescription = string.Format("im in ur long running job, doing ur work {0} of {1}...", this.OperationsPerformed, this.TotalOperationsToBePerformed);
                this.UpdateStatus();
                Thread.Sleep(1000);
            }
        }
    }
}