WF4 - 使用OutArgument时,复合自定义活动会抛出一个奇怪的异常

时间:2012-07-18 23:41:45

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

我正在尝试使用应用正则表达式的复合自定义活动,如果匹配则返回布尔值。 该模式是在设计时编码的东西。 源文本来自活动。此活动也在设计时指定(我已经创建了一个允许将活动作为源删除的活动设计器)

但是我还需要返回与表达式匹配的子字符串,所以我添加了一个OutArgument来检索匹配的字符串,并捕获字符串。

以下是代码:

public class RegularExpression : NativeActivity<bool>
{
    [RequiredArgument]
    public string Pattern { get; set; }

    public OutArgument<string> Captured { get; set; }

    [RequiredArgument]
    public Activity<string> RetrieveTextActivity { get; set; }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddChild(this.RetrieveTextActivity);
    }

    protected override void Execute(NativeActivityContext context)
    {
        if (this.RetrieveTextActivity != null)
            context.ScheduleActivity<string>(this.RetrieveTextActivity, this.onRetrieveComplete);
    }

    private void onRetrieveComplete(NativeActivityContext context, ActivityInstance completedInstance, string result)
    {
        var regexp = new Regex(this.Pattern);
        var match = regexp.Match(result);

        this.Result.Set(context, match.Success);
        if (this.Captured != null)
            this.Captured.Set(context, match.Value);
    }
}

如果我执行此活动没有将变量绑定到Captured参数,它将按预期工作(结果已正确设置)。
但是如果我使用设计器添加变量,那么我将变量绑定到Captured参数这个错误弹出:

  

不能使用“System.String”类型的参数。确保这一点   它是在一项活动中宣布的。

执行此行时抛出异常:

this.Captured.Set(context, match.Value);

有人知道为什么我不能设定论点吗? 我还读到我不应该测试Captured是否为null,运行时应该自动设置一个默认值。但是,如果我不测试,当我没有将变量绑定到参数时,我有一个NullReference ......

编辑:
我想添加有关工作流本身的更多信息。我在another topic读到可能是VS.在这里,我只想指定我使用重新设计的设计器来创建工作流程(而不是 VS)。然后将工作流程作为XML保存在数据库中 当我需要启动一个新的工作流程时,我会读取数据库,使用XamlService.Load并运行创建的工作流程。

2 个答案:

答案 0 :(得分:3)

如果在CacheMetadata声明参数?

,错误是否会消失
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    metadata.AddChild(this.RetrieveTextActivity);

    RuntimeArgument argument = new RuntimeArgument("Captured", typeof(string), ArgumentDirection.Out);
    metadata.Bind(this.Captured, argument);
    metadata.AddArgument(argument);

}
编辑:我太快了。上面的代码现在应该编译,希望能解决你的问题。

答案 1 :(得分:1)

我添加后,当我刚调用base.CachMetadata(元数据)时,我的问题就消失了。尝试:

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    metadata.AddChild(this.RetrieveTextActivity);
    base.CacheMetadata(metadata);
}

您希望在添加后执行此操作,因为您希望基类知道您在调用时添加的内容。我认为基类使用反射自动为你做Damir Arh的答案。这样,您每次添加或修改属性时都不必添加或修改所有代码。如果你有很多属性,它会很快变成痛苦。