How to: Use the QueueSystem Web Service

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Microsoft Office Project Server 2007 includes the Project Server Queuing service to handle jobs that can be long-running and to manage many simultaneous jobs. Project applications often need to determine when a job sent to the Project Server queue is complete, to continue with a process. This article show how to develop a method that uses the QueueSystem Web service to wait until a job is completed.

The Project Server Interface (PSI) includes many methods that begin with the name Queue, such as QueueSubmitTimesheet, QueueArchiveCustomFields, and QueueCreateProject. All asynchronous PSI methods use the Project Server Queuing Service and have names that begin with Queue. If the PSI method name does not begin with Queue, then the method is synchronous. The .NET Framework automatically adds asynchronous methods when wsdl.exe generates the Web service proxies; those auto-generated proxy methods do not use the Project Server Queuing service. For more information about the Asynch methods, see Using the PSI in Visual Studio.

Project Server has two queues:

The Timesheet queue manages jobs from queue-based methods in the Timesheet Web service.

The Project queue manages jobs such as save and publish from the other queue-based Web methods.

The QueueSystem class in the PSI includes methods that get an estimate of how long a job is going to take, find the job status, and cancel a job. The queue-based methods send a message with a job ID to the Project Server Queuing service to process a job. If the method spawns only one queue job, the method parameter includes the JobUid parameter. JobUid can be used for finding the job status in the queue. Some methods, such as QueueArchiveProjects and QueueUpgradeProject, spawn more than one queue job; they do not expose the JobUid parameter. For correlated jobs, the queue creates a job correlation GUID which you can use with methods such as GetJobCount, UnblockCorrelation, RetryCorrelation, GetProposedJobWaitTime, QueuePurgeArchivedJobs, and CancelCorrelation.

To track methods that spawn more than one job, you can use any of the methods that return a QueueStatusDataSet, such as ReadMyJobStatus.

To track multiple jobs that aren't necessarily correlated, set a tracking GUID on the SOAP header and use it to track the job group in the queue. A tracking GUID is the JobGroupGUID property in the QueueStatusDataSet and the QueueStatusRequestDataSet. For an example of how to set a tracking GUID on multiple jobs and how to use the QueueStatusRequestDataSet, see ReadJobStatus. For other examples that use a tracking GUID, see GetJobGroupWaitTime and GetJobGroupWaitTimeSimple.

This article shows how to create a queue utilities class and method that determines when a specified queue job is either complete or has exceeded a specified time, or when the job has an error condition in the Project Server Queuing service.

Important

WaitForQueue uses the Thread.Sleep method between checks for the queue job status. Blocking execution of a process in the server thread pool for a long duration or for many simultaneous processes, such as submitting timesheets, can severely impact the performance of Project Server. We recommend the WaitForQueue method for limited use in client applications only, not for server components.

Server components should not use Thread.Sleep in a tight loop such as in the WaitForQueue sample. Instead, an application that uses a server component for calls to PSI queue-based methods should display the job status and let the user refresh the application to update the job status field.

The sample WaitForQueue method includes a timeOut parameter so you can specify the maximum number of seconds to wait and cancel the job if it exceeds the time. The sample code returns the job status, including any error condition. To help show how the Project Server queue works, the WaitForQueue method also returns the initial Project Server Queuing service estimate of the number of seconds to complete the job and the actual number of seconds.

Procedure 1 shows how to create a queue utilities class with a WaitForQueue method that returns status and error information. Procedure 2 shows how to call the method from an application. For examples of status output, see Comments.

Procedure 1. To create a utility method that waits for a queue job:

Add a class to your application, for example QueueSystemUtils. Add the class constructor and necessary references, as in the following example. Your namespace will be different.

The INCREMENTALSLEEPTIME constant should be as many seconds as it takes a typical short queue job to complete.

Set a Web reference in the application to the QueueSystem Web service; for example, name the reference WebSvcQueueSystem.

Add a WaitForQueue method to the QueueSystemUtils class, which returns true for success and false for an error. WaitForQueue has the following parameters:

q is an instance of the QueueSystem class in the WebSvcQueueSystem namespace.

timeOut is the maximum number of seconds to wait for the queue job to complete.

jobId is the GUID of the queue job.

statusOut is an out parameter for the queue status. The sample method assigns the estimate of time to wait and the total actual time waited to statusOut, as well as the XML string of errors from the queue system.

When you add the QueueSystemUtils class to an application, modify the class namespace, add code to instantiate the class and call the WaitForQueue method, and then test the application. For example, Procedure 2 shows how you can use the QueueSystemUtils class in the application described in How to: Log on to Project Server Programmatically.

Procedure 2. To call the WaitForQueue method:

Change the namespace of the QueueSystemUtils class to the application namespace. For example, change the class namespace to LoginDemo.

Create a Web reference to the QueueSystem Web service. For example, name the Web service namespace WebSvcQueueSystem.

Set class constants and variables for the Web service and the results of the WaitForQueue method, and then instantiate the QueueSystem class, as follows.

Add the Url property and the Windows credentials for the Project Server forms logon cookie to the queueSystem object. The following code shows lined added to the AddContextInfo method in the LogonProjectServer.cs sample, in How to: Log on to Project Server Programmatically.

After you create a job GUID and call a queue-based method in your application, add the code to call WaitForQueue and handle the results for both success and failure. For example, the btnCreateProject_Click event handler sample code in LogonProjectServer.cs calls QueueCreateProject. The application must wait for the queue to add the project to the Draft database before calling QueuePublish. Comment out the System.Threading.Thread.Sleep(3000) line in the sample and add code after calling QueueCreateProject to test the WaitForQueue method, as follows:

The preceding code is an example for testing. In a production application you would likely not use a message box to show the queue status for a successful job. You could handle a failed job in other ways: for example, add information to a log file and create an application event for the Windows Event Viewer.

Following is the complete code for the WaitForQueue method in a class named QueueSystemUtils.

Note

WaitForQueue is designed for limited use in client applications. You should not use tight loops with calls to Thread.Sleep in server-side components, to avoid adversely affecting the server thread pool and degrading server performance.

The WaitForQueue method is a sample for test purposes. The GetJobCompletionState method returns error information in XML format in the xmlError parameter. If there are no errors, xmlError parameter contains the following:

The sample code adds the errinfo element only if it contains error data. If you want the statusOut parameter to return the estimated wait time and actual wait time as well-formed XML, you could add elements to the xmlError output from GetJobCompletionState so that the application could parse the entire statusOut results using XmlReader.

Following are examples of statusOut results for the sample WaitForQueue method in the LoginDemo test application. The initial estimates of time for the queue to process a QueueCreateProject job are often high when Project Server is newly installed. As Project Server continues to process jobs, the accuracy of the estimates from GetJobWaitTime improves.

Open the Services window and double-click the Microsoft Project Server Queuing (<SharedServicesName>) service. Set the Startup type to Disabled, click Apply, and then click Stop. Set the timeout to 20 seconds, and then try to create a project using the test application.