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