예제 #1
0
        /// <summary>
        /// Task completed executing in the task host
        /// </summary>
        private void HandleTaskHostTaskComplete(TaskHostTaskComplete taskHostTaskComplete)
        {
            // If it crashed, or if it failed, it didn't succeed.
            _taskExecutionSucceeded = taskHostTaskComplete.TaskResult == TaskCompleteType.Success ? true : false;

            // reset the environment, as though the task were executed in this process all along.
            CommunicationsUtilities.SetEnvironment(taskHostTaskComplete.BuildProcessEnvironment);

            // If it crashed during the execution phase, then we can effectively replicate the inproc task execution
            // behaviour by just throwing here and letting the taskbuilder code take care of it the way it would
            // have normally.
            // We will also replicate the same behaviour if the TaskHost caught some exceptions after execution of the task.
            if ((taskHostTaskComplete.TaskResult == TaskCompleteType.CrashedDuringExecution) ||
                (taskHostTaskComplete.TaskResult == TaskCompleteType.CrashedAfterExecution))
            {
                throw new TargetInvocationException(taskHostTaskComplete.TaskException);
            }

            // On the other hand, if it crashed during initialization, there's not really a way to effectively replicate
            // the inproc behavior -- in the inproc case, the task would have failed to load and crashed long before now.
            // Furthermore, if we were just to throw here like in the execution case, we'd lose the ability to log
            // different messages based on the circumstances of the initialization failure -- whether it was a setter failure,
            // the task just could not be loaded, etc.

            // So instead, when we catch the exception in the task host, we'll also record what message we want it to use
            // when the error is logged; and given that information, log that error here.  This has the effect of differing
            // from the inproc case insofar as ContinueOnError is now respected, instead of forcing a stop here.
            if (taskHostTaskComplete.TaskResult == TaskCompleteType.CrashedDuringInitialization)
            {
                string   exceptionMessage;
                string[] exceptionMessageArgs;

                if (taskHostTaskComplete.TaskExceptionMessage != null)
                {
                    exceptionMessage     = taskHostTaskComplete.TaskExceptionMessage;
                    exceptionMessageArgs = taskHostTaskComplete.TaskExceptionMessageArgs;
                }
                else
                {
                    exceptionMessage     = "TaskInstantiationFailureError";
                    exceptionMessageArgs = new string[] { _taskType.Type.Name,
                                                          AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly),
                                                          string.Empty };
                }

                _taskLoggingContext.LogFatalError(taskHostTaskComplete.TaskException, new BuildEventFileInfo(_taskLocation), taskHostTaskComplete.TaskExceptionMessage, taskHostTaskComplete.TaskExceptionMessageArgs);
            }

            // Set the output parameters for later
            foreach (KeyValuePair <string, TaskParameter> outputParam in taskHostTaskComplete.TaskOutputParameters)
            {
                _setParameters[outputParam.Key] = outputParam.Value?.WrappedParameter;
            }
        }
예제 #2
0
        public bool Execute()
        {
            // log that we are about to spawn the task host
            string runtime      = _taskHostParameters[XMakeAttributes.runtime];
            string architecture = _taskHostParameters[XMakeAttributes.architecture];

            _taskLoggingContext.LogComment(MessageImportance.Low, "ExecutingTaskInTaskHost", _taskType.Type.Name, _taskType.Assembly.AssemblyLocation, runtime, architecture);

            // set up the node
            lock (_taskHostLock)
            {
                _taskHostProvider = (NodeProviderOutOfProcTaskHost)_buildComponentHost.GetComponent(BuildComponentType.OutOfProcTaskHostNodeProvider);
                ErrorUtilities.VerifyThrowInternalNull(_taskHostProvider, "taskHostProvider");
            }

            TaskHostConfiguration hostConfiguration =
                new TaskHostConfiguration
                (
                    _buildComponentHost.BuildParameters.NodeId,
                    NativeMethodsShared.GetCurrentDirectory(),
                    CommunicationsUtilities.GetEnvironmentVariables(),
                    _buildComponentHost.BuildParameters.Culture,
                    _buildComponentHost.BuildParameters.UICulture,
#if FEATURE_APPDOMAIN
                    _appDomainSetup,
#endif
                    BuildEngine.LineNumberOfTaskNode,
                    BuildEngine.ColumnNumberOfTaskNode,
                    BuildEngine.ProjectFileOfTaskNode,
                    BuildEngine.ContinueOnError,
                    _taskType.Type.FullName,
                    AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly),
                    _buildComponentHost.BuildParameters.LogTaskInputs,
                    _setParameters,
                    new Dictionary <string, string>(_buildComponentHost.BuildParameters.GlobalProperties),
                    _taskLoggingContext.GetWarningsAsErrors(),
                    _taskLoggingContext.GetWarningsAsMessages()

                );

            try
            {
                lock (_taskHostLock)
                {
                    _requiredContext     = CommunicationsUtilities.GetHandshakeOptions(taskHost: true, taskHostParameters: _taskHostParameters);
                    _connectedToTaskHost = _taskHostProvider.AcquireAndSetUpHost(_requiredContext, this, this, hostConfiguration);
                }

                if (_connectedToTaskHost)
                {
                    try
                    {
                        bool taskFinished = false;

                        while (!taskFinished)
                        {
                            _packetReceivedEvent.WaitOne();

                            INodePacket packet = null;

                            // Handle the packet that's coming in
                            while (_receivedPackets.TryDequeue(out packet))
                            {
                                if (packet != null)
                                {
                                    HandlePacket(packet, out taskFinished);
                                }
                            }
                        }
                    }
                    finally
                    {
                        lock (_taskHostLock)
                        {
                            _taskHostProvider.DisconnectFromHost(_requiredContext);
                            _connectedToTaskHost = false;
                        }
                    }
                }
                else
                {
                    LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null);
                }
            }
            catch (BuildAbortedException)
            {
                LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null);
            }
            catch (NodeFailedToLaunchException e)
            {
                LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, e);
            }

            return(_taskExecutionSucceeded);
        }