工作流XAML自定义活动解析问题?

时间:2014-09-02 17:26:20

标签: customization workflow-foundation-4 workflow-activity

我创建了一个继承自NativeActivity和IActivityTemplateFactory的自定义XAML活动 Designer在我定义的库中显示正确的外观。

然而,当我将它放在工作流控制台应用程序的Flow Surface上时,我看不到它呈现。 CPU固定为50%,如果我运行procmon.exe,我会在.XAML文件上看到BUFFEROVERFLOW,在exe本身上看到NOT REPARSE错误。

我确实将typeof Designer定义为类的属性。

我已经在VS调试中打开了Exceptions,看看是否抛出了异常但是什么都没有出现。

- CODE-- CS

[Designer(typeof(ITCRetryActivityDesigner))]   
public sealed class ITCRetryActivity : NativeActivity, IActivityTemplateFactory
{
    private static readonly TimeSpan DefaultRetryInterval = new TimeSpan(0, 0, 0, 1);

    private readonly Variable<Int32> _attemptCount = new Variable<Int32>();

    private readonly Variable<TimeSpan> _delayDuration = new Variable<TimeSpan>();

    private readonly Delay _internalDelay;

    public ITCRetryActivity()
    {
        _internalDelay = new Delay
        {
            Duration = new InArgument<TimeSpan>(_delayDuration)
        };
        Body = new ActivityAction();
        MaxAttempts = 5;
        ExceptionType = typeof(TimeoutException);
        RetryInterval = DefaultRetryInterval;                
    }

    [DebuggerNonUserCode]
    public Activity Create(DependencyObject target)
    {
        return new ITCRetryActivity
               {
                   Body =
                       {
                           Handler = new Sequence()
                       }
               };
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddDelegate(Body);
        metadata.AddImplementationChild(_internalDelay);
        metadata.AddImplementationVariable(_attemptCount);
        metadata.AddImplementationVariable(_delayDuration);

        RuntimeArgument maxAttemptsArgument = new RuntimeArgument("MaxAttempts", typeof(Int32), ArgumentDirection.In, true);
        RuntimeArgument retryIntervalArgument = new RuntimeArgument("RetryInterval", typeof(TimeSpan), ArgumentDirection.In, true);

        metadata.Bind(MaxAttempts, maxAttemptsArgument);
        metadata.Bind(RetryInterval, retryIntervalArgument);

        Collection<RuntimeArgument> arguments = new Collection<RuntimeArgument>
                                                {
                                                    maxAttemptsArgument,
                                                    retryIntervalArgument
                                                };

        metadata.SetArgumentsCollection(arguments);
        ValidationError validationError;

        if (Body == null)
        {
            validationError = new ValidationError("No Children are defined in this Retry Activity", true, "Body"); 
            metadata.AddValidationError(validationError);
        }

        if (typeof (Exception).IsAssignableFrom(ExceptionType) != false) return;
        validationError = new ValidationError("Exception type does not match", false, "ExceptionType");

        metadata.AddValidationError(validationError);
    }

    protected override void Execute(NativeActivityContext context)
    {
        ExecuteAttempt(context);
    }

    private static Boolean ShouldRetryAction(Type exceptionType, Exception thrownException)
    {
        return exceptionType != null && exceptionType.IsInstanceOfType(thrownException);
    }

    private void ActionFailed(NativeActivityFaultContext faultcontext, Exception propagatedexception, ActivityInstance propagatedfrom)
    {
        Int32 currentAttemptCount = _attemptCount.Get(faultcontext);

        currentAttemptCount++;

        _attemptCount.Set(faultcontext, currentAttemptCount);

        Int32 maxAttempts = MaxAttempts.Get(faultcontext);

        if (currentAttemptCount >= maxAttempts)
        {
            // There are no further attempts to make
            return;
        }

        if (ShouldRetryAction(ExceptionType, propagatedexception) == false)
        {
            return;
        }

        faultcontext.CancelChild(propagatedfrom);
        faultcontext.HandleFault();

        TimeSpan retryInterval = RetryInterval.Get(faultcontext);

        if (retryInterval == TimeSpan.Zero)
        {
            ExecuteAttempt(faultcontext);
        }
        else
        {
            // We are going to wait before trying again
            _delayDuration.Set(faultcontext, retryInterval);

            faultcontext.ScheduleActivity(_internalDelay, DelayCompleted);
        }
    }

    private void DelayCompleted(NativeActivityContext context, ActivityInstance completedinstance)
    {
        ExecuteAttempt(context);
    }

    private void ExecuteAttempt(NativeActivityContext context)
    {
        if (Body == null)
        {
            return;
        }

        context.ScheduleAction(Body, null, ActionFailed);
    }

    [Browsable(false)]
    public ActivityAction Body
    {
        get;
        set;
    }

    [DefaultValue(typeof(TimeoutException))]
    public Type ExceptionType
    {
        get;
        set;
    }

    public InArgument<Int32> MaxAttempts
    {
        get;
        set;
    }

    public InArgument<TimeSpan> RetryInterval
    {
        get;
        set;
    }
}
}

- XAML -

<sap:ActivityDesigner x:Class="ITC.Common.Workflow.ITCRetryActivityDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
xmlns:conv="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation">
<sap:ActivityDesigner.Icon>
    <DrawingBrush>
        <DrawingBrush.Drawing>
            <ImageDrawing>
                <ImageDrawing.Rect>
                    <Rect Location="0,0"
                          Size="16,16">
                    </Rect>
                </ImageDrawing.Rect>
                <ImageDrawing.ImageSource>
                    <BitmapImage UriSource="d-metal-reload-arrows.jpg"></BitmapImage>
                </ImageDrawing.ImageSource>
            </ImageDrawing>
        </DrawingBrush.Drawing>
    </DrawingBrush>
</sap:ActivityDesigner.Icon>
<sap:ActivityDesigner.Resources>
    <conv:ModelToObjectValueConverter x:Key="ModelItemConverter"
                                      x:Uid="sadm:ModelToObjectValueConverter_1" />
    <DataTemplate x:Key="Collapsed">
        <TextBlock HorizontalAlignment="Center"
                   FontStyle="Italic"
                   Foreground="Gray">
            Double-Click to View
        </TextBlock>
    </DataTemplate>
    <DataTemplate x:Key="Expanded">
        <StackPanel Orientation="Vertical">
            <Grid Name="contentGrid">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                </Grid.RowDefinitions>

                <TextBlock Grid.Row="0"
                           Grid.Column="0"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center">
                    Exception Type:
                </TextBlock>
                <sapv:TypePresenter HorizontalAlignment="Left"
                                    VerticalAlignment="Center"
                                    Margin="6"
                                    Grid.Row="0"
                                    Grid.Column="1"
                                    Filter="ExceptionTypeFilter"
                                    AllowNull="false"
                                    BrowseTypeDirectly="false"
                                    Label="Exception Type"
                                    Type="{Binding Path=ModelItem.ExceptionType, Mode=TwoWay, Converter={StaticResource ModelItemConverter}}"
                                    Context="{Binding Context}" />
            </Grid>
            <sap:WorkflowItemPresenter Item="{Binding ModelItem.Body.Handler}"
                                       HintText="Drop Activity"
                                       Margin="6" />
        </StackPanel>
    </DataTemplate>
    <Style x:Key="ExpandOrCollapsedStyle"
           TargetType="{x:Type ContentPresenter}">
        <Setter Property="ContentTemplate"
                Value="{DynamicResource Collapsed}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=ShowExpanded}"
                         Value="true">
                <Setter Property="ContentTemplate"
                        Value="{DynamicResource Expanded}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</sap:ActivityDesigner.Resources>
<Grid>
    <ContentPresenter Style="{DynamicResource ExpandOrCollapsedStyle}"
                      Content="{Binding}" Height="16" VerticalAlignment="Top" />
</Grid>

我该如何调试这种情况?

感谢。

1 个答案:

答案 0 :(得分:0)

我解决了我的问题,删除了注释中所述的Exception类型,没有图标图形(使用默认值,因为它并不是那么重要。