Managed Operations. Design-Time Features

This document explains the features of the Managed Operations service available to the developer. It is recommended that you review the following topics before proceeding:

Content:

  • Synchronous operations. Displaying the process.
  • Creating the asynchronous operation.
  • Logging managed operations.
  • Unique managed operations.
  • Local and global managed operations.
  • CustomizeStatrMessage and CustomizeCompleteMessage events

Synchronous operations. Displaying the process.

There are four methods of the SyncManagedOperationHelper class, that can be used for displaying the process in different ways:

  • InitShowViewParameters()
  • InitShowViewParametersMarquee()
  • InitShowViewParametersProgress()
  • InitShowViewParametersSubprocess()

The second parameter specifies the way of closing the View after the process is finished:

True: the View closes automatically.

False: the View waits for a user action.

Note

There is one detail specific to Web-applications. This is evident when monitoring a Synchronous Managed Operation.

There is a Close button in the upper right corner of the popup window, which will close the window, but will not affect the process. This behavior is incorrect, as there is a special button to abort the process , and other options of getting out should not be. To remove the Close button from popup window, two ways are offered:

Implement IXafPopupWindowControlHolder interface in the page class. By default, this can be done with the Default.aspx.cs file.

An alternative is to change ID property of the XafPopupWindowControl in application, set "PopupWindowControl" value. If the application is created using a VS template, then "PopupWindowControl" is the default value.

Creating the asynchronous operation.

To implement an Asynchronous Managed Operation, you need to create an object of the Managed Operations class, as described in the Start here topic and the Sample. Subprocesses. If you don't use the SyncManagedOperationHelper class, then the created operation will run asynchronously by default.

Examples of asynchronous Managed Operations are included in the Xafari Northwind demo application.

managed_operations_9_1

You can see the respective code in the ManagedOperationsWindowController.cs file of the Xafari Northwind demo installed with Xafari.

Logging Managed Operations.

Execution of Managed Operations can be recorded in a log. The logging function allows for viewing and analysis of the history of execution of Managed Operations. Use the NextStep(string message, int message, int message) method to add information, including the percent progress value, to the log. Use the NextStep(string message) method to log the message only (without the percent progress value).

You can customize the logging parameters when initializing the operation. The following parameters are used to control the logging mechanism:

  • int Interval: specifies the time interval for updating information in the log file. It is set in milliseconds. The default value is 2000 milliseconds. If this parameter is 0, then the information is updated at each step.
  • bool Split: this flag controls splitting the log into blocks. The default value is False.
  • int Count: specifies the minimum count of records to be stored in one block. This parameter is used when log is split into blocks. The  default value is 1000 records. If Split == False, then the Count parameter is disregarded.

The following code snippet demonstrates, how to implement the logging to a single record; information is updated at 2 seconds intervals.

  • c#
  • VB

private void SyncProgress_Execute(object sender, SimpleActionExecuteEventArgs e)
{
  var operation = new Operation1(this.Application);
  var mo = new ManagedOperation(this.Application) { ZoneType = ((ActionBase)sender).Id == "SyncLocalProgress" ? ManagedOperationZoneTypes.Local : ManagedOperationZoneTypes.Global, Name = "SyncProgress", ProcessCode = (operation.Stage2), TotalStep = operation.Count, Split = false, Interval = 2000 };
  mo.Start();
  SyncManagedOperationHelper.CreateHelper(mo).InitShowViewParametersProgress(e.ShowViewParameters, false);
}

Private Sub SyncProgress_Execute(ByVal sender As Object, ByVal e As SimpleActionExecuteEventArgs)
  Dim operation = New Operation1(Me.Application)
  Dim mo = New ManagedOperation(Me.Application) With {.ZoneType = If(CType(sender, ActionBase).Id = "SyncLocalProgress", ManagedOperationZoneTypes.Local, ManagedOperationZoneTypes.[Global]), .Name = "SyncProgress", .ProcessCode = (operation.Stage2), .TotalStep = operation.Count, .Split = False, .Interval = 2000}
  mo.Start()
  SyncManagedOperationHelper.CreateHelper(mo).InitShowViewParametersProgress(e.ShowViewParameters, False)
End Sub

The following code shows splitting the log into blocks.

  • example

//...
 Split = true,
 Count = 12,
 Interval = 2000,
 //...

The figure below shows non-split and split log windows, respectively.

Win:

managed_operations_5_3

Warnings or errors can occur when the Managed Operation is running. In such situations, the logging is performed as follows:

if a warning is logged in the block, then the entire block decorates with the TraceMessageTypes.Warning type.

If an error is logged in the block, then the entire block decorates with the TraceMessageTypes.Error type.

If both errors and warnings are logged in the block, then the entire block decorates with the TraceMessageTypes.ErrorAndWarning type.

Logging and trace levels

The service may show only messages of defined levels of criticality in the log. This feature is provided by the TraceLevel property, the following values are available: Off, Errors, Warnings, Info, Verbose (see System.Diagnostics.TraceLevel enumeration).

In the case of long Managed Operations the Info and Verbose values have the same meaning, the system will log all progress information.

If you specify the Errors value, it will only errors are logged. Warnings value means warnings and errors. If you set the Off value, then the button to open the log will not be available on the form.

There are two ways to set TraceLevel:

  • Application config file (App.config/Web.config)
  • In code, when declaring operation

In the config file, use a XafariOperations variable

  • xml

<system.diagnostics>
 <switches>
 <!-- 0-Off, 1-Errors, 2-Warnings, 3-Info, 4-Verbose. -->
 <add name="eXpressAppFramework" value="3" />
 <add name="XafariManagedOperationsLogLevel" value="3"/>
 </switches>
 </system.diagnostics>

The following code demonstrates how to set TraceLevel after the operation was declared:

  • c#
  • VB

var mo = new ManagedOperation(this.Application) { ZoneType = ((ActionBase)sender).Id == "SyncLocalSubWithExceptions" ? ManagedOperationZoneTypes.Local : ManagedOperationZoneTypes.Global, Name = "Synchronous long process with sub-processes and exceptions", TracingStrategy = TracingStrategy.CopyToParent, TraceLevel = TraceLevel.Error };

Private mo As var = New ManagedOperation(Me.Application) With {.ZoneType = If(CType(sender, ActionBase).Id = "SyncLocalSubWithExceptions", ManagedOperationZoneTypes.Local, ManagedOperationZoneTypes.[Global]), .Name = "Synchronous long process with sub-processes and exceptions", .TracingStrategy = TracingStrategy.CopyToParent, .TraceLevel = TraceLevel.[Error]}

The value specified in the code, is a higher priority.

Unique Managed Operations

The Asynchronous Managed Operation that can only be started in one instance is called Unique Managed Operation. It is not possible to start another instance of the operation, if one Unique Operation is running. Before you can run such operation again, it is necessary to wait until the previous instance finishes.

To produce an example of unique operation, you need to modify the StartSimpleOperation_Execute() method from the Start here topic as follows:

  • c#
  • VB

private void StartSimpleOperation_Execute(object sender, SimpleActionExecuteEventArgs e)
{
  var simpleOperation = new SimpleOperation(this.Application);
  var operationId = new Guid("DCEDA7A6-B8E2-4306-AB52-0B0220C826CD");
  var managedOperation = new ManagedOperation(this.Application, operationId) { ZoneType = ManagedOperationZoneTypes.Local, Name = "Managed operation ", ProcessCode = (simpleOperation.ExecuteCore) };
  managedOperation.Start(false);
}

Private Sub StartSimpleOperation_Execute(ByVal sender As Object, ByVal e As SimpleActionExecuteEventArgs)
  Dim simpleOperation = New SimpleOperation(Me.Application)
  Dim operationId = New Guid("DCEDA7A6-B8E2-4306-AB52-0B0220C826CD")
  Dim managedOperation = New ManagedOperation(Me.Application, operationId) With {.ZoneType = ManagedOperationZoneTypes.Local, .Name = "Managed operation ", .ProcessCode = (simpleOperation.ExecuteCore)}
  managedOperation.Start(False)
End Sub

As you can see in the code above, a Unique Managed Operation is created using an overloaded constructor. The second parameter is a unique ID.

When attempting to launch it repeatedly, a message appears,  indicating that the launch is not permitted.

managed_operations_11

The message can be simple or detailed. The simple message is displayed after calling the start() method with the False parameter value. Otherwise the user will see an exception window.

An example of the Unique Operation is included in the Xafari Northwind demo application. You can see the respective code in the ManagedOperationsWindowController.cs file (the ASyncUnique_Execute() method).

Local and global Managed Operations

The ManagedOperation.ZoneType property determines the strategy of storing information on execution of the operation. If the ZoneType property is set to "ManagedOperationZoneTypes.Local" when initializing the operation, then the operation is local. ZoneType = "ManagedOperationZoneTypes.Global" specifies the global operation.

CustomizeStatrMessage and CustomizeCompleteMessage events

ManagedOperation class exposes CustomizeStatrMessage and CustomizeCompleteMessage events which allows to customize the messages at the begining and completing of the operation. Code snippet below demonstrates CustomizeCompleteMessage event handler:

  • c#
  • VB

public class SomeClass
{
  //...
  private void SomeMethod()
  {
    var managedOperation = new ManagedOperation(this.Application) { Name = CaptionHelper.GetLocalizedText(@"Texts\Tasks", "CompletingOperation"), TracingStrategy = TracingStrategy.OwnLevel, Split = true, TotalStep = e.SelectedObjects.Count, TraceLevel = TraceLevel.Warning, ZoneType = ManagedOperationZoneTypes.Local };
    managedOperation.CustomizeCompleteMessage += managedOperation_CustomizeCompleteMessage;
    //...
  }
  void managedOperation_CustomizeCompleteMessage(object sender, CustomizeMessageEventArgs e)
  {
    ((ManagedOperationItem)sender).CustomizeCompleteMessage -= managedOperation_CustomizeCompleteMessage;
    if (!string.IsNullOrEmpty(_operation.ResultMessage))
      e.Message = _operation.ResultMessage;
  }
}

Public Class SomeClass
  '...
  Private Sub SomeMethod()
    Dim managedOperation = New ManagedOperation(Me.Application) With {.Name = CaptionHelper.GetLocalizedText("Texts\Tasks", "CompletingOperation"), .TracingStrategy = TracingStrategy.OwnLevel, .Split = True, .TotalStep = e.SelectedObjects.Count, .TraceLevel = TraceLevel.Warning, .ZoneType = ManagedOperationZoneTypes.Local}
    managedOperation.CustomizeCompleteMessage += managedOperation_CustomizeCompleteMessage
    '...
  End Sub
  Private Sub managedOperation_CustomizeCompleteMessage(ByVal sender As Object, ByVal e As CustomizeMessageEventArgs)
    CType(sender, ManagedOperationItem).CustomizeCompleteMessage -= managedOperation_CustomizeCompleteMessage
    If Not String.IsNullOrEmpty(_operation.ResultMessage) Then
      e.Message = _operation.ResultMessage
    End If
  End Sub
End Class