关于wf中outArgument的错误

时间:2011-07-17 13:26:53

标签: workflow-foundation-4

当我使用书签在活动中声明OutArgument时,我收到以下错误!

  

“未提供所需活动参数'Out-arg'的值”

这是我的代码:

public string BookmarkName = "bookmark1 NameBookmark";        

[RequiredArgument]
public OutArgument<String> Out_arg { get; set; }

protected override void Execute(NativeActivityContext context)
{
    context.CreateBookmark(BookmarkName, new BookmarkCallback(OnBookmarkCallback));

    // Out_arg = new System.Activities.OutArgument<System.String>((string)val);
    // new ArgumentReference<string>("Out_arg");
}

protected override bool CanInduceIdle
{
    get
    {
        return true;
    }
}

void OnBookmarkCallback(NativeActivityContext context, Bookmark bookmark, object val)
{
     // Out_arg = new System.Activities.OutArgument<System.String>((string)val);
     // Out_arg = new OutArgument<String>((string)val);
     // Out_arg = ((string)val);
     Out_arg = new OutArgument<string>(new VisualBasicReference<string>((string)val));
}

First result

Second result

谢谢。

1 个答案:

答案 0 :(得分:4)

我觉得你是一个新的.NET开发人员。当你刚接触开发时,WF4并不是最简单的事情。框架使用了许多不明显的设计模式,只有经验丰富的开发人员才能掌握。我说这不是因为我很棒(虽然,坦率地说......)但是因为文档不清楚,而且关于WF4的资源还不多。

然而,您误解了如何在WF4中处理In / OutArguments。您必须set调用CacheMetadata之前的参数,然后使用参数的SetGet方法在运行时设置/获取参数的值。

WF4 Arguments模式是: Workflow运行时需要知道您的Activity计划做什么,并且必须为Workflow提供一种处理重要动态数据的方法(运行期间更改的数据)您的Activity需要运行。工作流运行时必须更改在运行时存储此数据并对其进行序列化/反序列化。

为了让Workflow执行此操作,它会为您提供In / Out / InOutArguments(和变量),您可以在其中存储易失性数据。在调用CacheMetadata期间,工作流了解这些实例并准备在运行时访问它们所需的工具。 如果在调用CacheMetadata之后对这些属性进行了更改,则工作流无法再获取/设置/序列化/反序列化这些实例包含的数据

因此,您必须设置一次,不要再次更改这些实例。您可以通过构造函数或实现IActivityTemplateFactory来完成此操作。

这是一个简单的例子:

public sealed class Negate : NativeActivity<bool>, IActivityTemplateFactory
{
    [RequiredArgument]
    public InArgument<bool> Input { get; set; }

    public Negate() 
    {
        // set it within the constructor option
        //Input = new InArgument<bool>();
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddArgument(Input);
        metadata.AddArgument(Result);
    }

    protected override void Execute(NativeActivityContext context)
    {
         // note the use of Get and Set methods
         Result.Set(context, !Input.Get(context));
    }

    Activity IActivityTemplateFactory.Create(DependencyObject target)
    { 
        // or we can set the Arguments here
        return new Negate 
        {
            Input = new InArgument<bool>(),
            Result = new OutArgument<bool>()
        };
    }
}
在设计图面上删除活动时调用

IActivityTemplateFactory.Create。删除后,将创建参数,该参数在调用CacheMetadata之前发生。这是配置这些的最好方法,imho。使用构造函数可能会导致一些意外的行为。请注意我们如何在CacheMetadata中告诉运行时我们希望运行时为我们跟踪的属性。调用该方法后,我们永远不会更改这些属性中保存的实例。我们只能在其上调用方法(例如GetSet)。

编辑:以下是调用这些方法的简单示例。

  • 用户从工具箱中拖动活动并将其放在设计图面上
  • 调用Create方法(在设计图面上创建Activity)
  • 调用CacheMetadata
  • 用户输入输入值
  • 调用CacheMetadata
  • 用户构建解决方案
  • 调用CacheMetadata
  • 用户运行解决方案
  • 创建工作流实例
  • 调用CacheMetadata
  • 工作流程执行
  • 执行称为
  • InArgument.Get称为
  • OutArgument.Set称为
  • 工作流程完成执行