Running Tasks

I've had some questions regarding how to run tasks via the SDK so I thought I would post an example here. The code below shows the various ways of executing tasks in the SDK. The underlying implementation relies on query notifications from SQL 2005 to notify us whenever the status of a particular batch changes; we actually register a new notification for every batch, but since the format of the notification is the same and only parameters change, the performance is not overly affected.

The code is pretty self-explanatory. I don't recommend using the synchronous version of the API because if something unexpected happens to the task your application will be stuck on the call until it times out (30 minutes) OR if you actually expect your task to take longer than 30 minutes, this version will timeout prior to your task completing. Also, if you don't care about getting notified of the results immediately, you can use the SubmitTask(s) API without providing a callback and simply query for results at a later time using the batch id you get from the call and the GetMonitoringTaskResults method available on both ManagementGroup and MonitoringObject.

using System;

using System.Collections.ObjectModel;

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.Monitoring;

 

namespace Jakub_WorkSamples

{

    partial class Program

    {

        static void RunningTasks()

        {

            // Connect to the local management group

            ManagementGroup mg = new ManagementGroup("localhost");

 

            // First lets get the task we are going to execute

            // Note: Indexing the result like this is not necessarily the best

            // practice here, since there could be more than one task with this

            // name.

            MonitoringTaskCriteria taskCriteria = new MonitoringTaskCriteria(

                "Name = 'Microsoft.SystemCenter.GetAllFailedWorkflows'");

            MonitoringTask failedWorkflowTask =

                mg.GetMonitoringTasks(taskCriteria)[0];

 

            // Configuration allows you to specify credentials to use different

            // from the default. It also allows you to specify overrides, if

            // any are available

            MonitoringTaskConfiguration failedWorkflowTaskConfiguration =

                new MonitoringTaskConfiguration();

 

            // Now we need to get an instance of a health service

            // First get the class

            MonitoringClass healthServiceClass =

                mg.GetMonitoringClass(SystemMonitoringClass.HealthService);

           

            // Next get the object (we'll just pick the first one)

            MonitoringObject healthServiceObject =

                mg.GetMonitoringObjects(healthServiceClass)[0];

 

            // Object centric task execution

           

            // Synchronous

            ReadOnlyCollection<MonitoringTaskResult> results =

                healthServiceObject.ExecuteMonitoringTask(failedWorkflowTask,

                failedWorkflowTaskConfiguration);

 

            // Asynchronous (standard .Net implementation)

            IAsyncResult asyncTaskResult =

                healthServiceObject.BeginExecuteMonitoringTask(

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                null, // You can specify a callback

                null); // And additional context

 

            results = healthServiceObject.EndExecuteMonitoringTask(asyncTaskResult);

 

            // Asynchronous (more advanced SCOM specific implementation)

            Guid batchId = healthServiceObject.SubmitMonitoringTask(failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                MyTaskCallback);

 

            // Task execution off ManagementGroup (for multiple targets)

            PartialMonitoringObject[] targets =

                new PartialMonitoringObject[] { healthServiceObject };

 

            // Synchronous

            results = mg.ExecuteMonitoringTask(targets, failedWorkflowTask,

                failedWorkflowTaskConfiguration);

 

            // Asynchronous (standard .Net implementation)

            asyncTaskResult =

                mg.BeginExecuteMonitoringTask(

                targets,

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                null, // You can specify a callback

                null); // And additional context

 

            results = mg.EndExecuteMonitoringTask(asyncTaskResult);

 

            // Asynchronous (more advanced SCOM specific implementation)

            batchId = mg.SubmitMonitoringTask(targets,

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                MyTaskCallback);

 

            // Wait for the task to complete

            System.Threading.Thread.Sleep(5000);

        }

 

        private static void MyTaskCallback(Guid batchId,

           ReadOnlyCollection<MonitoringTaskResult> results,

           bool completed)

        {

            if (completed)

            {

                Console.WriteLine("Batch Id {0} is done!", batchId);

            }

        }

    }

}