Using the CompensateActivity Activity
The CompensateActivity activity triggers the compensation of a completed activity that implements the ICompensatableActivity interface. Only activities that implement the ICompensatableActivity interface can be compensated. The two Windows Workflow Foundation out-of-box activities that implement the ICompensatableActivity interface are CompensatableTransactionScopeActivity and CompensatableSequenceActivity. You can also write custom activities that support compensation by using the ICompensatableActivity interface.
You do not have to use a CompensateActivity activity if there is no other compensation code in an outer compensatable activity. The compensation code of any nested successfully completed compensatable activities is run automatically if there is an unhandled exception in the workflow. You should use the CompensateActivity activity only when you need something other than default compensation. Default compensation invokes compensation of all nested ICompensatableActivity children in the reverse order of their completion. If this ordering is not what you need, or you want to selectively invoke compensation of completed ICompensatableActivity children, you should use the CompensateActivity activity.
Note
The CompensateActivity activity can only be used in a CompensationHandlerActivity activity, a CancellationHandlerActivity activity, or a FaultHandlerActivity activity.
The CompensateActivity activity gives you control over the compensation process by letting you decide whether you want to compensate an immediate child activity that supports compensation. If you use nested compensatable activities in your workflow, you can add a CompensateActivity activity in the compensation block or a faulthandler block of a compensatable activity. This enables your workflow to explicitly perform compensation on a nested compensatable activity. Specify which compensatable activity you want to be compensated in CompensateActivity, and any compensation code in the nested compensatable activity will be run, provided the compensatable activity committed successfully.
If you want to compensate more than one nested compensatable activity, add a CompensateActivity activity for each compensatable activity. However, if TargetActivityName is set to an activity that is associated with the CompensateActivity activity, then this will trigger compensation in all successfully completed nested activities that support compensation. The following example shows a workflow with a SequenceActivity activity that has a CompensateActivity activity referring to the SequenceActivity.
<SequenceActivity x:Name="sequenceActivity1">
<CompensatableSequenceActivity x:Name="compensatableSequenceActivity1">
<CompensatableSequenceActivity x:Name="compensatableSequenceActivity2">
<CompensationHandlerActivity x:Name="compensationHandlerActivity2">
<CodeActivity x:Name="Comp2Code" ExecuteCode="Comp2Code_ExecuteCode" />
</CompensationHandlerActivity>
</CompensatableSequenceActivity>
<CompensationHandlerActivity x:Name="compensationHandlerActivity1">
<CodeActivity x:Name="Comp1Code" ExecuteCode="Comp1Code_ExecuteCode" />
</CompensationHandlerActivity>
</CompensatableSequenceActivity>
<ThrowActivity x:Name="throwActivity1" Fault="{ActivityBind Workflow1,Path=throwActivity1_Fault1}" FaultType="{x:Type p6:Exception}" xmlns:p6="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<FaultHandlersActivity x:Name="faultHandlersActivity1">
<FaultHandlerActivity x:Name="faultHandlerActivity1" FaultType="{x:Type p8:Exception}" xmlns:p8="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<CompensateActivity x:Name="compensateActivity1" TargetActivityName="sequenceActivity1" />
</FaultHandlerActivity>
</FaultHandlersActivity>
</SequenceActivity>
When an exception is thrown from the ThrowActivity activity, the FaultHandlerActivity activity associated with the SequenceActivity activity handles the exception and calls the CompensateActivity activity. Because the CompensateActivity activity refers to the SequenceActivity activity, all compensation handlers are called on all nested compensatable activities. In this case, compensatable handlers for both CompensatableSequenceActivity activities are called.
For a code sample that demonstrates how to use the CompensateActivity activity, see Using Compensation.
See Also
Reference
CompensateActivity
CompensationHandlerActivity
ICompensatableActivity
CompensatableSequenceActivity
CompensatableTransactionScopeActivity
Concepts
Fault Handling in Workflows
Using Compensation in Workflows
Using the CompensatableSequenceActivity Activity
Using the CompensatableTransactionScopeActivity Activity
Compensation Overview
Adding Compensatable Activities and Compensation Handlers