Creating a background task handler in C#

This example shows how to create a custom background task handler to implement specific ways to process standard and custom events.

Before you begin

The following products need to be already installed on your machine:
  • Microsoft .NET FrameWork
  • Microsoft Visual Studio

Procedure

  1. Create a Visual Studio Project. In this example, the project is called MyCustomBackgroundTaskLibrary, and its type is Class Library.
  2. Add a reference to a plugin SDK (Trisoft.InfoShare.Plugins.SDK.dll). For example, you can copy the file from \Applications\Common\Trisoft.InfoShare.Plugins.SDK.dll.
    1. Browse to the project, then right-click References, and select Add Reference.
    2. To select the reference you want to add, click the Browse button.
    3. Select Trisoft.InfoShare.Plugins.SDK.dll, and click Add.
  3. Add a reference to the System.ComponentModel.Composition assembly.
  4. Add a reference to the System.Xml assembly.
  5. Create a new MyCustomHandler class.
    • The name of the background task handler corresponds to the value assigned to ExportAttribute, and it needs to be unique.
    • The LogService on IBackgroundTaskHandlerConfiguration manages all log entries as part of the standard log chaining, as configured in NLog.config. If you want to create a separate logging chain, you need to set up a new Logger
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml;
    using Trisoft.InfoShare.Plugins.SDK;
    using Trisoft.InfoShare.Plugins.SDK.BackgroundTasks;
    
    namespace MyCustomBackgroundTaskLibrary
    {
        // This attribute is used to make the class discoverable by the background task service.
        [Export("MyCustomHandler", typeof(IBackgroundTaskHandler))]
        [PartCreationPolicy(CreationPolicy.NonShared)]
        /// <summary>
        /// Custom background task handler that will be executed by the background task upon an event it is configured for.
        /// The handler logs the passed even input data into the event monitor with the configured action and description.
        /// </summary>
        public class MyCustomHandler : IBackgroundTaskHandler
        {
            // This variable is used to store the action passed through the parameters.
            private string _action;
            // This variable is used to store the description passed through the parameters.
            private string _description = String.Empty;
            /// <summary>
            /// The background task configuration
            /// </summary>
            private IBackgroundTaskHandlerConfiguration _configuration;
    
            /// <summary>
            /// The name of the event (e.g. "EXPORTFORPUBLICATION", "CREATETRANSLATIONFROMREPORT" etc.).
            /// Will be set by the background task service.
            /// </summary>
            public string EventTypeName
            {
                get;
                set;
            }
    
            /// <summary>
            /// This method will be called by the background task service after the instance of the handler is created.
            /// </summary>
            /// <param name="configuration">Parameters configured in the XML Background Task Settings.</param>
            public void Initialize(IBackgroundTaskHandlerConfiguration configuration)
            {
                _configuration = configuration;
    
                // Read the value of the required parameter from the background task xml configuration
                if (!_configuration.Parameters.TryGetValue("action", out _action))
                {
                    // If required parameter was not provided, throw (and log) an exception
                    var exception = new InvalidOperationException("action parameter was not provided");
                    _configuration.LogService.ErrorException(String.Format("Background task '{0}' failed", this.EventTypeName), exception);
                    throw exception;
                }
                // Read the value of the optional parameter from the background task xml configuration
                _configuration.Parameters.TryGetValue("description", out _description);
            }
    
            /// <summary>
            /// This method will be called by the background task service to run the handler.
            /// </summary>
            /// <param name="context">The context of the hander execution.</param>
            public void Run(IBackgroundTaskHandlerContext context)
            {
                try
                {
                    // Log the passed event data with the configured action/description
                    context.EventMonitor.AddEventDetail(
                        context.ProgressId, EventLevel.Information, _action, _description, DetailStatus.Success, EventDataType.Xml, context.InputDataStream);
    
                    // Add a message to the logging pipeline
                    _configuration.LogService.Info("Background handler has finished successfully for the event " + this.EventTypeName);
    
                    // Execution is successful, so end the event
                    context.EventMonitor.EndEvent(context.ProgressId, ProgressStatus.Success, 1, 1);
                }
                catch (Exception ex)
                {
                    // Add a message to the logging pipeline
                    _configuration.LogService.ErrorException("Background handler has failed for the event " + this.EventTypeName, ex);
    
                    // Background task service may retry the execution if configured, in that case, you cannot end the event yet
                    if (!context.WillRetryOnException(ex))
                    {
                        // If the retries are not configured, the service has exhausted the retry attempts, you need to end the event
                        context.EventMonitor.EndEvent(context.ProgressId, ProgressStatus.Failed, 1, 1);
                    }
                    throw;
                }
            }
    
            /// <summary>
            /// This method will be called by the plugin engine after all plugins have executed
            /// </summary>
            public void Dispose()
            {
                // In our example we don't need a cleanup
            }
        }
    }
              
  6. Deploy the new background task handler.
  7. Configure the new background task handler.
    
    <handler eventType="INBOXEXPORT">
      <scheduler executeSynchronously="false" />
      <authorization type="authenticationContext" />
      <execution timeout="01:00:00" recoveryGracePeriod="00:10:00" isolationLevel="None" useSingleThreadApartment="false" />
      <activator>
    	<net name="MyCustomHandler">
    	  <parameters>
    		<parameter name="action">My custom plugin</parameter>
    		<parameter name="description">Here attached you can find the event data passed to the handler.</parameter>
    	  </parameters>
    	</net>
      </activator>
      <errorHandler maximumRetries="0" />
    </handler>
              
  8. Restart the BackgroundTask service for the changes to become effective.