views:

18

answers:

1

Hi, I'm using a NativeActivity with a child activity called Body and a ActivityAction called OnFault, this is my code:

[Designer(typeof(RetryDesigner))]
public sealed class Retry : NativeActivity {

    public Activity Body { get; set; }
    public ActivityAction<Exception> OnFault { get; set; }

    protected override void CacheMetadata(NativeActivityMetadata metadata) {
        metadata.AddChild(Body);
        metadata.AddDelegate(OnFault);
        base.CacheMetadata(metadata);
    }

    protected override void Execute(NativeActivityContext context) {
        context.ScheduleActivity(Body, OnBodyCompleted, OnBodyFaulted);
    }

    void OnFaultCompleted(NativeActivityContext context, ActivityInstance instance) {
        context.ScheduleActivity(Body);
    }

    void OnBodyCompleted(NativeActivityContext context, ActivityInstance instance) {
    }

    void OnBodyFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom) {
        faultContext.HandleFault();

        if (OnFault != null) {
            faultContext.ScheduleAction<Exception>(OnFault, propagatedException, OnFaultCompleted);
        }
    }
}

and my main looks like this:

    static void Main(string[] args) {

        Variable<Exception> ex = new Variable<Exception>();
        DelegateInArgument<Exception> exception = new DelegateInArgument<Exception>();

        Retry retry = new Retry {
            Body = new Sequence {
                Variables = { ex },
                Activities = {
                    new Assign<Exception> {
                        To = new OutArgument<Exception>(ex),
                        Value = new InArgument<Exception>((env) => new Exception("test"))
                    },
                    new Throw {
                        Exception = ex
                    }
                }
            },
            OnFault = new ActivityAction<Exception> {
                Argument = exception,
                Handler = new Sequence {
                    Activities = {
                        new WriteLine{
                            Text = new InArgument<string>(env =>
                             exception.Get(env).Message)
                        }
                    }
                }
            }
        };

        var workflow = new WorkflowInvoker(retry);
        workflow.Invoke();

        Console.WriteLine();
    }

The problem is that the exception don't stop in the OnBodyFaulted callback and appear on the main as an unhedled expetion.

How can I stop the Exception inside the OnBodyFault callback, is there any state or property on the workflow to do that?

+1  A: 

The problem is that in the OnFaultCompleted() you are calling context.ScheduleActivity(Body) again. This time without a fault handler so that causes the same fault to occur again and the complete workflow to fault.

Maurice