How to Asynchronously Run a Management Pack Task

Applies To: Operations Manager 2007 R2, Operations Manager 2007 SP1, System Center Operations Manager 2007

Operations Manager Management Pack tasks can run in either a synchronous or an asynchronous mode. When an SDK client application runs a task in an asynchronous mode, the task runs in a separate thread. This allows the client to perform other operations while the task is running.

Example

  • The following example demonstrates how to asynchronously run a task to get the names of the rules and monitors that are running on all agent-managed computers in the Management Group.
/// <summary>
/// Asynchronously runs a task to get a list of all 
/// running rules or monitors on all agent-managed
/// computers in the Management Group.
/// </summary>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Administration;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Monitoring;
using System.Xml;
using System.Text;

namespace SDKSamples
{
    class Program
    {
        public static ManagementGroup mg = null;

        static void Main(string[] args)
        {
            mg = new ManagementGroup("localhost");

            Console.WriteLine("Asynchronously running a Management Pack task...");

            // Get the task.
            string query = "DisplayName = 'Show running rules and monitors for this health service'";
            MonitoringTaskCriteria taskCriteria = new MonitoringTaskCriteria(query);
            ReadOnlyCollection<MonitoringTask> tasks =
                mg.GetMonitoringTasks(taskCriteria);
            MonitoringTask task = null;
            if (tasks.Count == 1)
                task = tasks[0];
            else
                throw new InvalidOperationException(
                    "Error! Expected one task with: " + query);

            // Get the agent class.
            query = "Name = 'Microsoft.SystemCenter.ManagementServer'";
            MonitoringClassCriteria criteria = new MonitoringClassCriteria(query);
            ReadOnlyCollection<MonitoringClass> classes =
                mg.GetMonitoringClasses(criteria);
            if (classes.Count != 1)
                throw new InvalidOperationException(
                    "Error! Expected one class with: " + query);

            // Create a MonitoringObject list containing all agents (the 
            // targets of the task).
            List<MonitoringObject> targets = new List<MonitoringObject>();
            targets.AddRange(mg.GetMonitoringObjects(classes[0]));
            if (targets.Count < 1)
                throw new InvalidOperationException(
                    "Error! Expected at least one target.");

            // Use the default task configuration.
            MonitoringTaskConfiguration config = new MonitoringTaskConfiguration();

            // Run the task.
            Console.WriteLine("Starting task \"" + task.DisplayName +
                "\" on the following targets: ");
            foreach (MonitoringObject target in targets)
            {
                Console.WriteLine(target.DisplayName);
            }

            object state = null;
            IAsyncResult result = mg.BeginExecuteMonitoringTask(
                targets, task, config, new Program().OnAsyncTaskCallback, state);
            Console.WriteLine("Task started on " + targets.Count + " targets.");

            // Perform some operation while the tasks run, and wait for
            // the task results.
            System.Threading.Thread.Sleep(30000);

        }

        // The callback function is automatically called when the task is 
        // complete.
        private void OnAsyncTaskCallback(IAsyncResult result)
        {
            Console.WriteLine("OnAsyncTaskCallback started.");

            // Get the task results.
            ReadOnlyCollection<MonitoringTaskResult> results =
                mg.EndExecuteMonitoringTask(result);
            if (results.Count == 0)
                throw new InvalidOperationException("Error! Failed to return any results.");

            // Display the task results.
            int resultNo = 0;
            foreach (MonitoringTaskResult taskResult in results)
            {
                resultNo++;
                if (taskResult.Status == TaskStatus.Failed)
                {
                    Console.WriteLine("Target #" + resultNo + " failed.");
                    Console.WriteLine("Reason: " + taskResult.ErrorCode.Value);
                }
                else
                {
                    Console.WriteLine("Target #" + resultNo + " succeeded.");

                    // Convert the task Output element from a string to XML.
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(taskResult.Output);

                    // Parse and display the output.
                    string xPathQry = @"/DataItem/Count";
                    System.Xml.XmlNode countNode = xmlDoc.SelectSingleNode(xPathQry);
                    Console.WriteLine("Target contains " + countNode.InnerText + " running rules or monitors.");
                    xPathQry = @"//Workflow";
                    System.Xml.XmlNodeList instanceList = xmlDoc.SelectNodes(xPathQry);
                    int cnt = 0;
                    foreach (System.Xml.XmlNode thisInstance in instanceList)
                    {
                        cnt++;
                        Console.WriteLine(cnt.ToString() + ". " + thisInstance.InnerText);
                    }
                }
            }
        }
    }
}
' Asynchronously runs a task to get a list of all 
' running rules or monitors on all agent-managed
' computers in the Management Group.
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports Microsoft.EnterpriseManagement
Imports Microsoft.EnterpriseManagement.Administration
Imports Microsoft.EnterpriseManagement.Common
Imports Microsoft.EnterpriseManagement.Configuration
Imports Microsoft.EnterpriseManagement.Monitoring
Imports System.Xml
Imports System.Text


Namespace SDKSamples
    Class Program
        Public Shared mg As ManagementGroup = Nothing

        Public Overloads Shared Function Main(ByVal args() As String) As Integer

            mg = New ManagementGroup("localhost")

            Console.WriteLine("Asynchronously running a Management Pack task...")

            ' Get the task.
            Dim query As String = "DisplayName = 'Show running rules and monitors for this health service'"
            Dim taskCriteria As New MonitoringTaskCriteria(query)
            Dim tasks As ReadOnlyCollection(Of MonitoringTask) = mg.GetMonitoringTasks(taskCriteria)
            Dim task As MonitoringTask = Nothing
            If tasks.Count = 1 Then
                task = tasks(0)
            Else
                Throw New InvalidOperationException("Error! Expected one task with: " + query)
            End If

            ' Get the agent class.
            query = "Name = 'Microsoft.SystemCenter.ManagementServer'"
            Dim criteria As New MonitoringClassCriteria(query)
            Dim classes As ReadOnlyCollection(Of MonitoringClass) = mg.GetMonitoringClasses(criteria)
            If classes.Count <> 1 Then
                Throw New InvalidOperationException("Error! Expected one class with: " + query)
            End If

            ' Create a MonitoringObject list containing all agents (the 
            ' targets of the task).
            Dim targets As List(Of MonitoringObject) = New List(Of MonitoringObject)
            targets.AddRange(mg.GetMonitoringObjects(classes(0)))
            If targets.Count < 1 Then
                Throw New InvalidOperationException("Error! Expected at least one target.")
            End If

            ' Use the default task configuration.
            Dim config As New MonitoringTaskConfiguration()

            ' Run the task.
            Console.WriteLine(("Starting task """ + task.DisplayName + """ on the following targets: "))
            Dim target As MonitoringObject
            For Each target In targets
                Console.WriteLine(target.DisplayName)
            Next target

            Dim state As Object = Nothing
            Dim callback As New AsyncCallback(AddressOf New Program().OnAsyncTaskCallback)
            Dim result As IAsyncResult = mg.BeginExecuteMonitoringTask( _
                targets, task, config, callback, state)
            Console.WriteLine(("Task started on " + targets.Count.ToString() + " targets."))

            ' Perform some operation while the tasks run, and wait for
            ' the task results.
            System.Threading.Thread.Sleep(30000)
        End Function 'Main


        ' The callback function is automatically called when the task is 
        ' complete.
        Private Sub OnAsyncTaskCallback(ByVal result As IAsyncResult)
            Console.WriteLine("OnAsyncTaskCallback started.")

            ' Get the task results.
            Dim results As ReadOnlyCollection(Of MonitoringTaskResult) = mg.EndExecuteMonitoringTask(result)
            If results.Count = 0 Then
                Throw New InvalidOperationException("Error! Failed to return any results.")
            End If
            ' Display the task results.
            Dim resultNo As Integer = 0
            Dim taskResult As MonitoringTaskResult
            For Each taskResult In results
                resultNo += 1
                If taskResult.Status = TaskStatus.Failed Then
                    Console.WriteLine("Target #" + resultNo.ToString() + " failed.")
                    Console.WriteLine("Reason: " + taskResult.ErrorCode.Value.ToString())
                Else
                    Console.WriteLine("Target #" + resultNo.ToString() + " succeeded.")

                    ' Convert the task Output element from a string to XML.
                    Dim xmlDoc As New XmlDocument()
                    xmlDoc.LoadXml(taskResult.Output)

                    ' Parse and display the output.
                    Dim xPathQry As String = "/DataItem/Count"
                    Dim countNode As System.Xml.XmlNode = xmlDoc.SelectSingleNode(xPathQry)
                    Console.WriteLine("Target contains " + countNode.InnerText + " running rules or monitors.")
                    xPathQry = "//Workflow"
                    Dim instanceList As System.Xml.XmlNodeList = xmlDoc.SelectNodes(xPathQry)
                    Dim cnt As Integer = 0
                    Dim thisInstance As System.Xml.XmlNode
                    For Each thisInstance In instanceList
                        cnt += 1
                        Console.WriteLine(cnt.ToString() + ". " + thisInstance.InnerText)
                    Next thisInstance
                End If
            Next taskResult
        End Sub 'OnAsyncTaskCallback
    End Class 'Program
End Namespace 'SDKSamples

See Also

Tasks

How to Synchronously Run a Management Pack Task