ThreadAsynchronizer Pattern (Version V7)

Often it’s necessary to do “something” in an asynchronous way; for example, to use a long running task. Of course, in our sample nothing really needs to be long. But I prefer using a different thread or task for short running tasks an asynchronous way. This also assures a responsive UI because the affected flow might be extended in the future. I try to avoid resultant problems because of these customizations / extensions.

In our example we “asynchronize” the steps to set the alarm time. To do this we insert a new pattern based step called “AsynchronizeString” between the UI step and the first “business logic” step. The following diagram shows the extended flows of the application:
As you see I prefer a combination of verb and data type, eg. message as name. Feel free to define you own convention! Now let’s take a look at the resulting application description. The following snippet only shows the affected flow description:
$App GlobalStepDefinitions {
   $Step MainWindow { CustomName = "UI" PreparedInstance = "True" SingleInstance = "True" }
   $Step TimerClock { SingleInstance = "True" }
   $Step CalculateRemainTime { SingleInstance = "True" }
   $Step SynchronizeDateTime { Pattern = "Synchronizer" }
   $Step AsynchronizeString { Pattern = "ThreadAsynchronizer" 
      PatternParameters = "ThreadOptions=IsBackgroundThread, LockOptions=LockedThread" }

$Flow SetAlarmTimeFlow {        
    $Wire UI?AlarmDuration -> AsynchronizeString
    $Wire AsynchronizeString -> ConvertToDouble?StringInputPin
    $Wire ConvertToDouble -> CalculateAlarmTime
    $Wire CalculateAlarmTime -> CalculateRemainTime?AlarmTime

The step “AsynchronizeString” is defined in a global scope. If you use this step ounce, you can also define the step in flow scope.

The only thing we have to do is to define this step (by keyword “$Step”) and to specify which pattern (in this case “ThreadAsynchronizer”) is used. This pattern needs some parameters. These are defined by key word “PatternParameters”.

You should use the parameter value “IsBackgroundThread” at “ThreadOptions” if the resulting thread is a background thread of the application. This means that if the application is closed, the thread will also be terminated immediately. If you use the value “IsIndipendantThread” the thread will stay “alive” until the “work is done” even if the user decides to exit the application. This is useful to store necessary data (for example configuration data to file, or to save data within a database) that may not be lost.

The second parameter called “LockOptions” specifies how to process new “jobs” while the old is still running. If you set to “LockedThread” the previous will be finished first and then the new one will be started (like a queue). This is useful to prevent concurring data from being changed. By using “UnlockedThread”, a new thread will be created immediately after receiving new data.

Last, we have to modify the wires to use the new step between UI and the first step of the business logic. That’s all that’s needed to be changed. There are no implementations to change. The desired data type is detected by the source code generating part of the AD4.AppDesigner. We just have to recreate the new gluing code by button “Code” and to rebuild the sample application. Then the application is ready to use.

Currently only a thread based asynchronizer is supported. Since version 4 of the .NET-Framework Microsoft suggests using the Task-Class instead. The implementation of the TaskAsynchronizer as a pattern, is planned for a future version of the AD4.AppDesigner and will soon follow.

In this pattern, everything that can be explained by this sample has been said. The following section does not using the sample application anymore.

Download: example 'AD4.Tutorial.V7.Sourcecode' at AD4.TutorialSamples
Update (2015-03-30): This page is obsolete. You find the current version of the tutorial as offline documentation included in downloads...

Previous: Synchronizer Pattern (Version V6)
Next: ConvertToTrigger Pattern

Last edited Mar 30, 2015 at 8:19 AM by InneHo, version 12