Microsoft SharePoint and .NET Technology Insight

SharePoint, .NET, Office365, Windows Azure, TFS, Project Server and SQL Server Technology Insights


1 Comment

Using SPLongOperation for Synchronous Long running tasks in SharePoint

The Microsoft.SharePoint.SPLongOperation class is useful when providing consistent user feedback to users during long running synchronous operation. The documentation tells us that this class “Sets the Web page image to the image used by the server to indicate a lengthy operation (typically, an animated image with associated text)”.

For example, consider a scenario in which a SharePoint Web-Part page is used to add users to an External system by using a WCF service. The add user process maybe a lengthy operation based on the available business logic within the external system and can be wrapped in a SPLongOperation by calling the static SPLongOperation.Begin Method (String, String, SPLongOperation.BeginOperation) where the SPLongOperation.BeginOperation delegate specifies the delegate method that will begin the long operation. There are 2 string parameters which set the SPLongOperation.LeadingHTML and SPLongOperation.TrailingHTML properties (what is displayed as “the associated text”). When the call to the WCF service is completed successfully, the operation is ended by calling either the End or EndScript method, based on whether the window was opened as a dialog or not which can be verified if the query string parameter “IsDlg”, which will be equal to 1 if it is a dialog window. Here is an example for using SPLongOperation:

try
{
    SPLongOperation.Begin(
        "Calling WCF Service for adding user into External System",
        "Please wait for this process to complete. This may take a few seconds.",
        delegate(SPLongOperation longOp)
        {
            try
            {
                //Code for calling the WCF service for adding a user into an External System goes here

                // Now end the long operation
                if (Context.Request.QueryString["IsDlg"] != null)
                {
                    longOp.EndScript(String.Format(CultureInfo.InvariantCulture,
                        "<script type=\"text/javascript\">window.frameElement.commonModalDialogClose({0}, {1});</script>",
                        1, String.Format("\"{0}\"", returnValue)));
                }
                else
                {
                    string url = Context.Request.UrlReferrer.AbsoluteUri;
                    longOp.End(url,
                       Microsoft.SharePoint.Utilities.SPRedirectFlags.DoNotEndResponse,HttpContext.Current,"");
                }
            }
            catch (ThreadAbortException) { /* thrown when redirected */ }
            catch (Exception ex)
            {
                string exMessage = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
                string message = String.Format("Error occurred whilst deleting relationship: {0}", exMessage);
                RedirectToErrorPage(message);
            }
        });
}
catch (ThreadAbortException) { /* thrown when redirected */ }
catch (Exception ex)
{
    string exMessage = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
    string message = String.Format("Error occurred when calling WCF Service add a user into External System: {0}", exMessage);
    RedirectToErrorPage(message);
}

//The RedirectToErrorPage(message) method calls the SPUtility.TransferToErrorPage method
private void RedirectToErrorPage(string message)
{
    if (string.IsNullOrEmpty(this.Referrer))
    {
        SPUtility.TransferToErrorPage(message);
    }
    else
    {
        SPUtility.TransferToErrorPage(String.Concat(message, " {0}."), "Return to calling Web-Part page.", this.Referrer);
    }
}

Additional information on SPLongOperation can be found here:

http://blog.symprogress.com/2010/10/close-modal-dialog-when-splongoperation-finish/

http://dotnetfollower.com/wordpress/2011/08/sharepoint-how-to-use-splongoperation/