Freigeben über


ResourcePlan.QueueCreateResourcePlan-Methode

Erstellt einen neue Ressourcenplan.

Namespace:  WebSvcResourcePlan
Assembly:  ProjectServerServices (in ProjectServerServices.dll)

Syntax

'Declaration
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/QueueCreateResourcePlan", RequestNamespace := "https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/",  _
    ResponseNamespace := "https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/",  _
    Use := SoapBindingUse.Literal, ParameterStyle := SoapParameterStyle.Wrapped)> _
Public Sub QueueCreateResourcePlan ( _
    projectUid As Guid, _
    rpds As ResourcePlanDataSet, _
    timephasedFTE As Boolean, _
    autoCheckIn As Boolean, _
    jobUid As Guid _
)
'Usage
Dim instance As ResourcePlan
Dim projectUid As Guid
Dim rpds As ResourcePlanDataSet
Dim timephasedFTE As Boolean
Dim autoCheckIn As Boolean
Dim jobUid As Guid

instance.QueueCreateResourcePlan(projectUid, _
    rpds, timephasedFTE, autoCheckIn, _
    jobUid)
[SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/QueueCreateResourcePlan", RequestNamespace = "https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/", 
    ResponseNamespace = "https://schemas.microsoft.com/office/project/server/webservices/ResourcePlan/", 
    Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public void QueueCreateResourcePlan(
    Guid projectUid,
    ResourcePlanDataSet rpds,
    bool timephasedFTE,
    bool autoCheckIn,
    Guid jobUid
)

Parameter

  • projectUid
    Typ: System.Guid

    Enthält die Projekt-GUID.

  • timephasedFTE
    Typ: System.Boolean

    Wenn true, erstellen Sie mit Zeitphasen Vollzeit entsprechende Ressourcen.

  • autoCheckIn
    Typ: System.Boolean

    Wenn die veröffentlichte Datenbank nach der Erstellung true, die Ressource einchecken möchten.

  • jobUid
    Typ: System.Guid

    Die GUID des Warteschlangenauftrags enthält.

Beispiele

Im Beispiel wird den SvcResourcePlan -Namespace in der Assembly für ProjectServerServices.dll Proxy verwendet. Die Methoden SetResPlanClientEndPoints, SetQueueClientEndPoints, SetProjectClientEndPointsund SetResourceClientEndPoints Verwenden einer App für den WCF-Bindung, Verhalten und Endpunkt festlegen. Informationen zum Erstellen einer PSI-Proxy-Assembly und eine App finden Sie unter Prerequisites for WCF-Based Code Samples.

Hinweis

Das folgende Beispiel veranschaulicht die Verwendung der QueueCreateResourcePlan -Methode; Es ist keine vollständige Lösung.

Die GenerateResourcePlan -Methode ruft GenerateResources um zwei Ressourcen zu erstellen und die GenerateProject -Methode zum Erstellen eines Projekts. Im nächsten Schritt der angegebenen Länge ein Ressourcenplans erstellt, und planen die Ressourcen hinzugefügt wird. Nachdem sie die Ressourcen hinzugefügt hat, die GenerateResourcePlan -Methode ruft GetIntervalNameByDate , um die Intervalle zu erhalten und festgelegt, dass die Arbeit für die einzelnen Intervalle durch Aufrufen der SetWorkForResourceForInterval -Methode.

Intervallen werden generiert, wenn die ResourcePlan wird vom Server basierend auf den Datumsbereich und die Zeitskala gelesen, aber in Project Web App, Sie nur, die Ressourceninformationen und die Zeitphasendaten mit sehen. Beispielsweise beim Lesen des Ressourcenplans mit einen Datumsbereich und für die Zeitskala (Intervall) (z. B. von 1/1/2010 um 12/31/2010 Monate) gibt es zwölf Zeilen oder Intervallen in der Tabelle Dates . Diese Zeilen haben Namen, die Spalten in der Tabelle PlanResources sind. Dies wird in der folgende Codeausschnitt veranschaulicht.

// Read the ResourcePlan.
            SvcResourcePlan.ResourcePlanDataSet rpds = 
                new SvcResourcePlan.ResourcePlanDataSet();
            rpds = resourcePlanClient.ReadResourcePlan("", projUid, 
                DateTime.Now, endDate, 
                (short)PSLibrary.ResourcePlan.TimeScale.Months, false, false);

Wenn der Wert der Arbeit für ein bestimmtes Intervall festlegen möchten, finden Sie die Ressourcenzeile (nach RES_UID) und den Namen der Intervall (aus der Tabelle Dates , beispielsweise Interval0 , Interval11). Legen Sie den Wert es in Projekteinheiten (z. B. 4800 für 1 Tag der Arbeit), wie im folgenden Codeausschnitt dargestellt.

SvcResourcePlan.ResourcePlanDataSet.DatesRow drow = 
                rds.Dates.FindByIntervalName(intervalName);
            if (drow == null)
            {
                Console.WriteLine("Failed to set value for interval {0}. Did not find interval.", 
                    intervalName);
                return;
            }
            SvcResourcePlan.ResourcePlanDataSet.PlanResourcesRow prow = 
                rds.PlanResources.FindByRES_UIDPROJ_UID(resourceGuid, pGuid);
            prow[intervalName] = value * PSLibrary.ValidationConst.s_cal_units_per_hour; // 8*60*10 = 4800

Schließlich wird die QueueCreateResourcePlan -Methode aufgerufen, um den Ressourcenplan zu erstellen. Die Zeitskala verwendet ist Monate und die mit Zeitphasen Vollzeit äquivalente auf falsefestgelegt sind. Der vollständige Beispielcode lautet wie folgt.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceModel;
using System.Data;
using System.Xml;
using PSLibrary = Microsoft.Office.Project.Server.Library;

namespace Microsoft.SDK.Project.Samples.ResourcePlan
{

    class TimephasedResourcePlan
    {

        private const string ENDPOINT_RESPLAN = "basicHttp_ResourcePlan";
        private const string ENDPOINT_Q = "basicHttp_QueueSystem";
        private const string ENDPOINT_R = "basicHttp_Resource";
        private const string ENDPOINT_P = "basicHttp_Project";
        private const string OUTPUT_FILES = @"C:\Project\Samples\Output\";
        private const string XML_FILE1 = "ResourcePlanDS.xml";
        private const string XML_FILE2 = "UpdatedResourcePlanDS.xml";

        private static SvcResourcePlan.ResourcePlanClient resourcePlanClient;
        private static SvcQueueSystem.QueueSystemClient queueSystemClient;
        private static SvcResource.ResourceClient resourceClient;
        private static SvcProject.ProjectClient projectClient;
        private static string outFile_ResourcePlanDS;
        private static string outFile_UpdatedResourcePlanDS;

        private static List<Guid> createdResources = new List<Guid>();
        private static List<Guid> createdProjects = new List<Guid>();
        private static PSLibrary.ResourcePlan.TimeScale timescale = 
            new PSLibrary.TimeScaleClass.TimeScale();
        private static int numResources = 2;    // Default number of resources to create.
        private static int numDays = 10;        // Default number of days for the plan.
        private static bool deletePlan = true;  // Delete the plan, project, and resources after creating them.

        static void Main(string[] args)
        {
            timescale = PSLibrary.TimeScaleClass.TimeScale.Months; // Default timescale.

            try
            {
                if (args.Length > 1 && args.Length < 9)
                {
                    if (args[0].ToLower() == "-delete")
                    {
                        deletePlan = Convert.ToBoolean(args[1]);
                    }
                    if (args.Length > 3)
                    {
                        if (args[2].ToLower() == "-timescale")
                            switch (args[3].ToLower())
                            {
                                case "days":
                                    timescale = PSLibrary.TimeScaleClass.TimeScale.Days;
                                    break;
                                case "quarters":
                                    timescale = PSLibrary.TimeScaleClass.TimeScale.Quarters;
                                    break;
                                case "weeks":
                                    timescale = PSLibrary.TimeScaleClass.TimeScale.Weeks;
                                    break;
                                case "years":
                                    timescale = PSLibrary.TimeScaleClass.TimeScale.Years;
                                    break;
                                default:
                                    timescale = PSLibrary.TimeScaleClass.TimeScale.Months;
                                    break;
                            }
                    }
                    if (args.Length > 5)
                    {
                        if (args[4].ToLower() == "-numresources")
                            numResources = Convert.ToInt32(args[5]);

                    }
                    if (args.Length > 7)
                    {
                        if (args[6].ToLower() == "-numdays")
                            numDays = Convert.ToInt32(args[7]);
                    }
                }

                // Configure the endpoints.
                bool configResult = false;
                configResult = ConfigClientEndpoints(ENDPOINT_RESPLAN);
                configResult = ConfigClientEndpoints(ENDPOINT_Q);
                configResult = ConfigClientEndpoints(ENDPOINT_P);
                configResult = ConfigClientEndpoints(ENDPOINT_R);

                if (!configResult) throw new ApplicationException();

                // If output directory does not exist, create it.
                if (!Directory.Exists(OUTPUT_FILES))
                {
                    Directory.CreateDirectory(OUTPUT_FILES);
                }

                // Set the output file path.
                outFile_ResourcePlanDS = OUTPUT_FILES + XML_FILE1;
                outFile_UpdatedResourcePlanDS = OUTPUT_FILES + XML_FILE2;

                try
                {
                    bool createAssignments = true;

                    GenerateResourcePlan(numResources, numDays, createAssignments);
                }
                catch (FaultException fault)
                {
                    // Use the WCF FaultException, because the ASMX SoapException does not 
                    // exist in a WCF-based application.
                    WriteFaultOutput(fault);
                }
                catch (CommunicationException e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(
                        "\n***System.ServiceModel.CommunicationException\n{0}:", e.Message);
                    Console.ResetColor();
                }
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("\n\n***Exception:\n{0}", ex.Message);
                Console.ResetColor();
            }
            Console.Write("\nPress any key to exit: ");
            Console.ReadKey(true);
        }

        // Extract a PSClientError object from the WCF FaultException object, and
        // then display the exception details and each error in the PSClientError stack.
        private static void WriteFaultOutput(FaultException fault)
        {
            string errAttributeName;
            string errAttribute;
            string errOut;
            string errMess = "".PadRight(30, '=') + "\r\n"
                + "Error details: " + "\r\n";

            PSLibrary.PSClientError error = Helpers.GetPSClientError(fault, out errOut);
            errMess += errOut;

            if (error != null)
            {
                PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
                PSLibrary.PSErrorInfo thisError;

                for (int i = 0; i < errors.Length; i++)
                {
                    thisError = errors[i];
                    errMess += "\r\n".PadRight(30, '=') + "\r\nPSClientError output:\r\n";
                    errMess += thisError.ErrId.ToString() + "\n";

                    for (int j = 0; j < thisError.ErrorAttributes.Length; j++)
                    {
                        errAttributeName = thisError.ErrorAttributeNames()[j];
                        errAttribute = thisError.ErrorAttributes[j];
                        errMess += "\r\n\t" + errAttributeName
                            + ": " + errAttribute;
                    }
                }
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(errMess);
            Console.ResetColor();
        }

        /// <summary>
        /// Generate the resource plan.
        /// </summary>
        /// <param name="resourceCount">Number of resources.</param>
        /// <param name="lengthInDays">Length of the resource plan in days.</param>
        /// <param name="generateAssignmentValues">True to generate assignment values.</param>
        public static void GenerateResourcePlan(int resourceCount, 
            int lengthInDays, bool generateAssignmentValues)
        {
            // Create enterprise resources.
            Guid[] resGuids = GenerateResources(resourceCount);

            // Create a project.
            Guid projUid = GenerateProject();

            // Create a resource plan DataSet of the specified duration.
            int daysLeft = lengthInDays;
            DateTime endDate = DateTime.Now;

            while (daysLeft > 0)
            {
                endDate = endDate.AddDays(1);
                if (!(endDate.DayOfWeek == DayOfWeek.Saturday 
                    || endDate.DayOfWeek == DayOfWeek.Sunday))
                    --daysLeft;
            }

            // Read the resource plan.
            string resPlanFilter = string.Empty;
            bool fteTime = false;
            bool autoCheckOut = false;

            SvcResourcePlan.ResourcePlanDataSet rpds = 
                resourcePlanClient.ReadResourcePlan(resPlanFilter, projUid,
                DateTime.Now, endDate, (short)timescale, fteTime, autoCheckOut);

            // Add the resources to the resource plan DataSet.
            for (int i = 0; i < resGuids.Length; i++)
            {
                SvcResourcePlan.ResourcePlanDataSet.PlanResourcesRow newRes = 
                    rpds.PlanResources.NewPlanResourcesRow();

                newRes.RES_UID = resGuids[i];
                newRes.ASSN_BOOKING_TYPE = 
                    (byte)PSLibrary.Resource.BookingType.Proposed;
                newRes.PROJ_UID = projUid;
                rpds.PlanResources.AddPlanResourcesRow(newRes);
            }

            // Set the resource utilization date limit.
            SvcResourcePlan.ResourcePlanDataSet.UtilizationRow utilizationRow =
                rpds.Utilization.NewUtilizationRow();
            utilizationRow.RESPLAN_UTILIZATION_TYPE = 
                (int)PSLibrary.ResourcePlan.UtilizationType.FromResourcePlan;
            utilizationRow.RESPLAN_UTILIZATION_DATE = new DateTime(2031, 2, 20);
            utilizationRow.PROJ_UID = projUid;

            if (rpds.Utilization.Count == 0)
            {
                rpds.Utilization.AddUtilizationRow(utilizationRow);
            }

            // Set assignment values.
            if (generateAssignmentValues)
            {
                for (DateTime d = DateTime.Now; d <= endDate; d = d.AddDays(1))
                {
                    // Set the number of hours in each workday.
                    double workVal = (d.DayOfWeek == DayOfWeek.Saturday || 
                        d.DayOfWeek == DayOfWeek.Sunday) 
                        ? 0 
                        : 8;

                    string interval = GetIntervalNameByDate(d, rpds);

                    foreach (Guid res in resGuids)
                    {
                        SetWorkForResourceForInterval(interval, res,
                            projUid, workVal, rpds);
                    }
                }
            }

            // Create the resource plan.
            Guid jobGuid = Guid.NewGuid();
            int numJobs = 1;
            bool autoCheckIn = false;
            resourcePlanClient.QueueCreateResourcePlan(projUid, rpds,
                fteTime, autoCheckIn, jobGuid);

            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ResourcePlanSave,
                   numJobs, queueSystemClient, jobGuid);
            Console.WriteLine("Resource plan created successfully.");

            // Publish the resource plan.
            resourcePlanClient.QueuePublishResourcePlan(projUid, jobGuid);

            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ResourcePlanPublish,
                   numJobs, queueSystemClient, jobGuid);
            Console.WriteLine("Resource plan published.");

            // Read the resource plan.
            rpds = resourcePlanClient.ReadResourcePlan(resPlanFilter, projUid, DateTime.Now,
                endDate, (short)timescale, fteTime, autoCheckOut);

            // Write the ResourcePlan DataSet to an XML file.
            rpds.WriteXml(outFile_ResourcePlanDS);
            Console.WriteLine("\nSee XML output of resource plan DataSet at\n\t{0}",
                outFile_ResourcePlanDS);
            Console.Write("\nPress any key to continue: ");
            Console.ReadKey(true);
            
            // Change the booking type for a resource and update the resource plan.
            Guid updateJob = Guid.NewGuid();

            rpds.PlanResources[0].ASSN_BOOKING_TYPE = 
                (int)PSLibrary.Resource.BookingType.Committed;
            resourcePlanClient.QueueUpdateResourcePlan(projUid, rpds, 
                fteTime, autoCheckIn, updateJob);

            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ResourcePlanSave,
                  numJobs, queueSystemClient, jobGuid);
            Console.WriteLine("Resource plan updated successfully.");

            // Write the updated resource plan DataSet to an XML file.
            rpds.WriteXml(outFile_UpdatedResourcePlanDS);
            Console.WriteLine("\nSee XML output of the updated resource plan DataSet at \n\t{0}",
                outFile_UpdatedResourcePlanDS);

            if (deletePlan)
            {
                Console.WriteLine("\nPress any key to continue");
                Console.Write("...and delete the resource plan, project, and resources:");
                Console.ReadKey(true);
                DeleteResourcePlan(projUid, resGuids);
            }
        }

        // Delete the resource plan and the test project and resources.
        public static void DeleteResourcePlan(Guid projUid, Guid[] resUids)
        {
            // QueueDeleteResourcePlan takes an array of project GUIDs and job GUIDs.
            Guid deleteResPlanJob = Guid.NewGuid();
            Guid[] deleteJobs = new Guid[1] { deleteResPlanJob };
            Guid[] projects = new Guid[1] { projUid };

            resourcePlanClient.QueueDeleteResourcePlan(projects, deleteJobs);

            int numJobs = 1;
            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ResourcePlanDelete,
                                 numJobs, queueSystemClient, deleteResPlanJob);

            Guid projDeleteJob = Guid.NewGuid();
            bool deleteProjectSite = false;  // No project site was created during publish.
            bool deleteInPubAndDraftDb = true;
            projectClient.QueueDeleteProjects(projDeleteJob, deleteProjectSite, 
                                              projects, deleteInPubAndDraftDb);
            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectDelete,
                                 numJobs, queueSystemClient, projDeleteJob);

            // Resources must be checked out before they can be deleted.
            resourceClient.CheckOutResources(resUids);
            string noComment = string.Empty;
            resourceClient.DeleteResources(resUids, noComment);

            Console.WriteLine("Resource plan, project, and resources deleted successfully.");             
        }

        // Create the specified number of enterprise resources.
        public static Guid[] GenerateResources(int numRes)
        {
            Console.WriteLine("Creating {0} resources:", numRes.ToString());
            Guid[] resUids = new Guid[numRes];
            SvcResource.ResourceDataSet rds = new SvcResource.ResourceDataSet();
            for (int i = 0; i < numRes; i++)
            {
                SvcResource.ResourceDataSet.ResourcesRow resRow = 
                    rds.Resources.NewResourcesRow();
                resRow.RES_UID = Guid.NewGuid();

                string resName = "Res Name " + resRow.RES_UID;
                Console.WriteLine("\t {0}", resName);
                resRow.RES_NAME = resName;

                rds.Resources.AddResourcesRow(resRow);
                resUids[i] = resRow.RES_UID;
            }
            resourceClient.CreateResources(rds, false, true);
            createdResources.AddRange(resUids);
            return resUids;
        }

        // Create a project.
        public static Guid GenerateProject()
        {
            SvcProject.ProjectDataSet pds = new SvcProject.ProjectDataSet();
            SvcProject.ProjectDataSet.ProjectRow pRow = pds.Project.NewProjectRow();
            pRow.PROJ_UID = Guid.NewGuid();

            string projName = "Proj " + pRow.PROJ_UID;
            Console.WriteLine("Creating project: {0}", projName);
            pRow.PROJ_NAME = projName;
            pds.Project.AddProjectRow(pRow);

            Guid jobUid = Guid.NewGuid();
            projectClient.QueueCreateProject(jobUid, pds, false);

            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectCreate,
                           1, queueSystemClient, jobUid);
            Guid joubUid = Guid.NewGuid();
            string mssUrl = string.Empty;   // Don't create a project site.
            bool fullPublish = true;
            projectClient.QueuePublish(jobUid, pRow.PROJ_UID, fullPublish, mssUrl);
            Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectPublish, 1, 
                queueSystemClient, jobUid);
            createdProjects.Add(pRow.PROJ_UID);
            return pRow.PROJ_UID;
        }

        // Get the assignment interval name.
        public static string GetIntervalNameByDate(DateTime date, 
            SvcResourcePlan.ResourcePlanDataSet resDS)
        {
            foreach (SvcResourcePlan.ResourcePlanDataSet.DatesRow row in resDS.Dates)
                if (date >= row.StartDate && date < row.EndDate)
                    return row.IntervalName;
            return string.Empty;
        }

        // Set work for a resource, for the specified interval.
        public static void SetWorkForResourceForInterval(string intervalName, 
            Guid resourceGuid, 
            Guid projUid, double value, 
            SvcResourcePlan.ResourcePlanDataSet rpds)
        {
            SvcResourcePlan.ResourcePlanDataSet.DatesRow datesRow = 
                rpds.Dates.FindByIntervalName(intervalName);
            if (datesRow == null)
            {
                Console.WriteLine("\nFailed to set value for interval: {0}. Did not find interval.", 
                    intervalName);
                return;
            }
            SvcResourcePlan.ResourcePlanDataSet.PlanResourcesRow planRow = 
                rpds.PlanResources.FindByRES_UIDPROJ_UID(resourceGuid, projUid);
            planRow[intervalName] = value * PSLibrary.ValidationConst.s_cal_units_per_hour;
        }

        // Configure the PSI client endpoints.
        public static bool ConfigClientEndpoints(string endpt)
        {
            bool result = true;

            switch (endpt)
            {
                case ENDPOINT_RESPLAN:
                    resourcePlanClient = new SvcResourcePlan.ResourcePlanClient(endpt);
                    break;
                case ENDPOINT_P:
                    projectClient = new SvcProject.ProjectClient(endpt);
                    break;
                case ENDPOINT_Q:
                    queueSystemClient = new SvcQueueSystem.QueueSystemClient(endpt);
                    break;
                case ENDPOINT_R:
                    resourceClient = new SvcResource.ResourceClient(endpt);
                    break;
                default:
                    result = false;
                    Console.WriteLine("Invalid endpoint: {0}", endpt);
                    break;
            }
            return result;
        }        
    }
    class Helpers
    {
        /// <summary>
        /// Public TimeOut property.
        /// </summary>
        /// <value>Gets or sets the timeout for WaitForQueue calls.</value>
        public static int TimeOut
        {
            get
            {
                return timeOut;
            }
            set
            {
                timeOut = value;
            }
        }
        // Default timeout is 3 minutes.
        private static int timeOut = 3 * 60 * 1000;

        // Incremental sleep time is 2 seconds.
        private static int incrementalSleepTime = 2 * 1000;

        public static SvcQueueSystem.JobState WaitForQueue(
            SvcQueueSystem.QueueMsgType jobType, int numJobs,
            SvcQueueSystem.QueueSystemClient queueSystemClient, Guid jobId)
        {
            int timeSlept = 0;
            int sleepInterval = (TimeOut / 60 > incrementalSleepTime) ? 
                TimeOut / 60 : incrementalSleepTime;

            SvcQueueSystem.QueueStatusDataSet queueStatusDs = 
                new SvcQueueSystem.QueueStatusDataSet();
            String errorString = String.Empty;
            Console.WriteLine("\nWaiting for job" + jobType.ToString());

            while (true)
            {
                SvcQueueSystem.JobState jobState = 
                    queueSystemClient.GetJobCompletionState(out errorString, jobId);

                SvcQueueSystem.QueueStatusDataSet jobStatus = 
                    queueSystemClient.ReadJobStatusSimple(new Guid[] { jobId }, true);
                if (jobState == SvcQueueSystem.JobState.Unknown)
                {
                    string jobStatusInfo = "Job status is unknown.";
                    jobStatusInfo += "\n\tWas the job placed on the Queue?";
                    jobStatusInfo += "\n\t--returning from WaitForQueue.";
                    Console.WriteLine(jobStatusInfo);
                    return jobState;
                }
                if (jobState == SvcQueueSystem.JobState.Success ||
                    jobState == SvcQueueSystem.JobState.Failed ||
                    jobState == SvcQueueSystem.JobState.FailedNotBlocking ||
                    jobState == SvcQueueSystem.JobState.CorrelationBlocked ||
                    jobState == SvcQueueSystem.JobState.Canceled)
                {
                    Console.WriteLine("\tJob completed, returning from WaitForQueue");
                    return jobState;
                }
                System.Threading.Thread.CurrentThread.Join(sleepInterval);
                timeSlept += sleepInterval;

                if (timeSlept > TimeOut)
                {
                    return SvcQueueSystem.JobState.Unknown;
                }
            }
        }

        /// <summary>
        /// Extract a PSClientError object from the ServiceModel.FaultException,
        /// for use in output of the GetPSClientError stack of errors.
        /// </summary>
        /// <param name="e"></param>
        /// <param name="errOut">Shows that FaultException has more information 
        /// about the errors than PSClientError has. FaultException can also contain 
        /// other types of errors, such as failure to connect to the server.</param>
        /// <returns>PSClientError object, for enumerating errors.</returns>
        public static PSLibrary.PSClientError GetPSClientError(FaultException e,
                                                               out string errOut)
        {
            const string PREFIX = "GetPSClientError() returns null: ";
            errOut = string.Empty;
            PSLibrary.PSClientError psClientError = null;

            if (e == null)
            {
                errOut = PREFIX + "Null parameter (FaultException e) passed in.";
                psClientError = null;
            }
            else
            {
                // Get a ServiceModel.MessageFault object.
                var messageFault = e.CreateMessageFault();

                if (messageFault.HasDetail)
                {
                    using (var xmlReader = messageFault.GetReaderAtDetailContents())
                    {
                        var xml = new XmlDocument();
                        xml.Load(xmlReader);

                        var serverExecutionFault = xml["ServerExecutionFault"];
                        if (serverExecutionFault != null)
                        {
                            var exceptionDetails = serverExecutionFault["ExceptionDetails"];
                            if (exceptionDetails != null)
                            {
                                try
                                {
                                    errOut = exceptionDetails.InnerXml + "\r\n";
                                    psClientError =
                                        new PSLibrary.PSClientError(exceptionDetails.InnerXml);
                                }
                                catch (InvalidOperationException ex)
                                {
                                    errOut = PREFIX + "Unable to convert fault exception info ";
                                    errOut += "a valid Project Server error message. Message: \n\t";
                                    errOut += ex.Message;
                                    psClientError = null;
                                }
                            }
                            else
                            {
                                errOut = PREFIX + "The FaultException e is a ServerExecutionFault, "
                                    + "but does not have ExceptionDetails.";
                            }
                        }
                        else
                        {
                            errOut = PREFIX + "The FaultException e is not a ServerExecutionFault.";
                        }
                    }
                }
                else // No detail in the MessageFault.
                {
                    errOut = PREFIX + "The FaultException e does not have any detail.";
                }
            }
            errOut += "\r\n" + e.ToString() + "\r\n";
            return psClientError;
        }
    }
}

Siehe auch

Referenz

ResourcePlan Klasse

ResourcePlan-Member

WebSvcResourcePlan-Namespace