如何在完成父项之前安排子活动执行*?

时间:2013-10-29 12:50:19

标签: .net-4.5 workflow-foundation-4 workflow-activity

我有一个WF(4.5)工作流活动,它创建一个子工作流(评估VisualBasicValue表达式)。我需要结果之前我完成了父工作流程。

我将表达式添加到元数据中,如下所示:

private VisualBasicValue<string> _expression;

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    base.CacheMetadata(metadata); 
    var visualBasicValue = (VisualBasicValue<string>)(_childActivity.Text.Expression);
    var expressionText = visualBasicValue.ExpressionText;
    _expression = new VisualBasicValue<string>(expressionText);
    metadata.AddChild(_expression);
}

我尝试在Execute方法中安排活动,如下所示:

protected override void Execute(NativeActivityContext context)
{
    context.ScheduleActivity(context, _expression, OnCompleted);
    Result.Set(context, _value);
}

回调:

private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance, string result)
{
    _value = result;
}

不幸的是,_expression活动仅在父执行方法返回后执行。将它添加为实现子元素不起作用(它不能用作实现子元素,因为它应该评估包含父元素外部变量的表达式。)

如何克服这个问题并在执行环境中执行?

2 个答案:

答案 0 :(得分:1)

在代码中,就像在现实生活中一样,你无法安排过去的事情(但是:)。

ScheduleActivity()会将活动放在执行队列中并尽快执行。由于父活动仍在运行,_ 表达式只会在它之后执行。最重要的是,这是一个异步调用。

如果要控制何时调用_ 表达式,只需使用WorkflowInvoker即可随时同步执行。

public class MyNativeActivity : NativeActivity
{
    private readonly VisualBasicValue<string> _expression;

    public MyNativeActivity()
    {
        // 'expression' construction logic goes here
        _expression = new VisualBasicValue<string>("\"Hi!\"");
    }

    protected override void Execute(NativeActivityContext context)
    {
        var _value = WorkflowInvoker.Invoke(_expression);

        Console.WriteLine("Value returned by '_expression': " + _value);

        // use '_value' for something else...
    }
}

答案 1 :(得分:0)

我花了几天时间,但我设法解决了自己的问题(没有违反WF工作原理的正常情况)。

我最终做的是,使用反射,迭代孩子的属性,并在 CacheMetadata <中创建每个参数的LinkedList评估表达式(使用VisualBasicValue) / strong>方法。然后在执行阶段,我安排了第一次评估的执行。在其回调中,我迭代剩余的评估,安排下一次评估的执行,将结果添加到字典中,直到完成。

最后,如果没有更多的评估要安排,我会安排一个最终活动,它将字典作为参数,并可以用它做任何想做的事情。在自己的之后,它可选地将最终结果返回给容器的OutArgument。

我之前未能理解的是,即使调度发生在实例化活动的执行之后,回调也会在控制权返回到主机工作流应用程序之前运行,并且在那个空间中我可以工作。