Advanced programming


From .NET you know the principle of asynchronous programming and the declaration of asynchronous methods with the async-keyword. Unfortunately, this works only in the same Applicationdomain and not network wide.

The iPlus framework provides the concept of "Points for asynchronous methods" for network-transparent asynchronous programming:


In the Events chapter, the principle of callback methods in connection with points was explained.

Asynchronous methods are based on the same design pattern and are merely an extended implementation (blue dashed frame):

 

IACPointAsyncRMI<T> inherits from two interfaces:

  1. IACPointNet<T, W> - A network-capable IACPoint<W> that is able to transmit its ConnectionList property over the network.
  2. IACPointNetService<T, W>, which represents a "service point". In an abstract sense, a service point provides a service for its ConnectionList entries.

The class ACPointAsyncRMI implements IACPointAsyncRMI<T>. ACPointAsyncRMIinstances allow components to provide asynchronous methods that can be called network-wide. The asynchronous calls are entered into the ConnectionList. Consumers (components from the same or a remote application domain) cannot fill the ConnectionList directly but require the IACPointAsyncRMISubscr interface:

IACPointAsyncRMISubscr<T> inherits from two interfaces:

  1. IACPointNet<T, W> - A network-capable IACPoint<W> that is able to transmit its ConnectionList property over the network.
  2. IACPointNetClient, which represents a "client point". In an abstract sense, a client point represents a consumer that uses services from service points.

The class ACPointAsyncRMISubscr implements IACPointAsyncRMISubscr<T>.


The IACPointAsyncRMISubscr<T> interface is used to call asynchronous methods. As with the subscription of events, a callback method must be passed as a delegate and additionally a virtual method (parameter acMethod):

ACPointAsyncRMISubscrWrap<T> InvokeAsyncMethod(IACComponent atACComponent, string asyncRMIPointName, ACMethod acMethod, ACPointNetEventDelegate AsyncCallbackDelegate);

ACPointAsyncRMISubscrWrap<T> InvokeAsyncMethod(IACComponent atACComponent, string asyncRMIPointName, ACMethod acMethod, ACPointNetEventDelegate AsyncCallbackDelegate, bool AutoRemove);

ACPointAsyncRMISubscrWrap<T> InvokeAsyncMethod(IACComponent atACComponent, string asyncRMIPointName, ACMethod acMethod, string asyncCallbackDelegateName);

ACPointAsyncRMISubscrWrap<T> InvokeAsyncMethod(IACComponent atACComponent, string asyncRMIPointName, ACMethod acMethod, string asyncCallbackDelegateName, bool AutoRemove);

 


Asynchronous methods must have

[ACMethodAsync("Process", "en{'Example asynchronous method'}de{'Beispiel asynchrone Methode'}", 999, false)]
public virtual ACMethodEventArgs ExampleMethodAsync (ACMethod acMethod)

ACPointAsyncRMI points are labeled with the ACPropertyAsyncMethodPoint attribute class and the asynchronous method is labeled with ACMethodAsync.

After instantiating the ACPointAsyncRMI class in the constructor, the SetMethod delegate is assigned with the "OnSetInvocationPoint" method. It is called whenever a new entry is made in the ConnectionList or a new asynchronous call is added. The implementation of the SetMethod delegate can be individual. The following example code calls the DeQueueInvocationList() method, which starts all new entries (variant A). Internally, it calls the ActivateAsyncRMI() method as it is alternatively programmed under variant B:

 

Typically, asynchronous methods do its job in other threads. It is also usually traversing a state machine that notifies the caller that the asynchronous method has completed until it reaches its end state. This is done by calling the InvokeCallbackDelegate() method.  Let's see how the callback is invoked on client side in the following section:


The ACPointAsyncRMISubscr client point must be labeled with the ACPropertyAsyncMethodPointSubscr attribute class. The last parameter is optionally the name of the default callback method. The callback method is passed when the InvokeAsyncMethod() method is called to call the "ExampleMethodAsync" method asynchronously. The name of the "ExampleMethodAsync" method does not need to be passed because the "MixingTemperature" virtual method implicitly knows it:

 

Synchronous calls

Asynchronous methods can also be called synchronously as it is programmed in the example method "InvokeVirtualMethodSync" above. Please keep in mind that the calling thread is blocked until asynchronous processing is performed. This approach is therefore not recommended unless you know the runtime behavior of the asynchronous method and this blocking effect has been taken into account.

Synchronous calls are similar to the await operator in C# - but network-transparent.

 


Workflows

Workflows loaded at run time redirect their persistent virtual methods to the asynchronous start method of process functions in the physical model. However, the point for asynchronous method calls is not declared in the PAProcessFunction class, but in its parent class (ParentACComponent), which is of type PAProcessModule.

PAProcessModule implements the interface IACComponentTaskExec. The interface requires, that the implementing class provides the ACPointTask TaskInvocationPoint point. ACPointTask is just a derivation of ACPointAsyncRMI. ACPointTask persists its ConnectionList in the ACClassTaskValuePos table, unlike the ACPointAsyncRMI base class, which serializes the ConnectionList as XML and stores it in the ACClassTaskValue table.

 

Implementing the methods of IACComponentTaskExec:

If you want to use ACPointTask yourself, you should use the IACComponentTaskExec interface and implement the following methods in this way:

public virtual bool ActivateTask(ACMethod acMethod, bool executeMethod, IACComponent executingInstance)
{
return ACPointAsyncRMIHelper.ActivateTask(this, acMethod, executeMethod, executingInstance);
}

public virtual bool CallbackTask(ACMethod acMethod, ACMethodEventArgs result, PointProcessingState state)
{
return ACPointAsyncRMIHelper.CallbackTask(this, acMethod, result, state);
}

public virtual bool CallbackTask(IACTask task, ACMethodEventArgs result, PointProcessingState state)
{
return ACPointAsyncRMIHelper.CallbackTask(this, task, result, state);
}

public IACTask GetTaskOfACMethod(ACMethod acMethod)
{
return ACPointAsyncRMIHelper.GetTaskOfACMethod(this, acMethod);
}

public virtual bool CallbackCurrentTask(ACMethodEventArgs result)
{
return ACPointAsyncRMIHelper.CallbackCurrentTask(this, result);
}

Delegate only the calls to the methods of the ACPointAsyncRMIHelper class. These methods are only helper methods for a somewhat simplified way of dealing with the callback methods. Please use these methods instead of ACPointNetAsyncRMI<T>. InvokeCallbackDelegate().