[WF4] Simuler un Break

Publié le 22 mai 2014 par Jeremy.jeanson

Note: Voici un article qui m’a été demandé il y a bien longtemps et qui malheureusement s’est perdu dans ma boite à idées... désolé

De base, il n’existe pas de notion de break dans Workflow Foundation (et par chance il n’y a pas non plus de GoTo). Pour disposer d’un break, il faut donc ruser. L’astuce consiste à utiliser la seule activité TryCatch et de lui faire capturer une exception particulière.

Pour l’occasion, j’ai une exception simple (autant dire qu’elle ne sert à rien seule):

public sealed class BreackException : Exception
{
}

Et une activité Break (ne pas oublier l’attribut DebuggerHidden pour ne pas bloquer le debugger)

/// <summary>
/// Throw a BreackException
/// </summary>
public sealed class Break : CodeActivity
{
    /// <summary>
    /// Execute
    /// </summary>
    /// <param name="context"></param>
    [DebuggerHidden()]
    protected override void Execute(CodeActivityContext context)
    {
        throw new BreackException();
    }

    /// <summary>
    /// Cache
    /// </summary>
    /// <param name="metadata"></param>
    protected override void CacheMetadata(CodeActivityMetadata metadata)
    {
        // Nothing to register
    }
}

Pour utiliser cet ensemble, il suffit d’ajouter une activité TryCatch. On utilise le lien “Add new catch”

On choisit ensuite de parcourir la liste des types d’exceptions disponibles

On choisit l’exception custom “BreakException” citée un peu plus haut. Dans mon exemple, elle se trouve dans le même projet (ne pas oublier de compiler le projet avant)

On revient ensuite au bloc Try en utilisant le lien “Add an activity” (en haut à droite du TryCatch)

On peut alors glisser son activité “Break”. Libre à vous de glisser ce que vous voulez autour du break.

Pour l’occasion, j’ai réalisé un exemple complet avec une boucle ParallelForEach :

L’énumération “items” contient par défaut l’expression C# suivante “new[] { 1,2,3,4,5,6}”.

Ce qui donne à l’exécution :

Lorsqu’item à la valeur 4, le break a lieu. La solution est simple et efficace. Ai passage, on prouve bien qu’un ParallelForEach  peut être interrompu sans problèmes et sans risquer de briser la persistance si elle est utilisée (détail auquel il faut toujours faire attention quand on fait du Workflow Foundation).