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
Important: The information and the procedure herein are provided as is without warranty of any kind, either express or implied.
The following products need to be already installed on your machine:
- Microsoft .NET FrameWork 4.5
- Microsoft Visual Studio 2013
Procedure
- Create a Visual Studio Project. In this example, the project is called
MyCustomBackgroundTaskLibrary, and its type is Class Library. - 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.
- Browse to the project, then right-click References, and select Add Reference.
- To select the reference you want to add, click the Browse button.
- Select Trisoft.InfoShare.Plugins.SDK.dll, and click Add.
- Add a reference to the System.ComponentModel.Composition assembly.
- Add a reference to the System.Xml assembly.
- 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", "PUSHTRANSLATIONS" 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 } } } - Deploy the new background task handler.
- 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> - Restart the BackgroundTask service for the changes to become effective.