1

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

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

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 活动仅在父级的执行方法返回后执行。将其添加为实现子项不起作用(它不能作为实现子项工作,因为它应该评估包含父项外部变量的表达式)。

任何想法如何克服这一点并在执行上下文中执行?

4

2 回答 2

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...
    }
}
于 2013-10-29T14:42:55.963 回答
0

我花了几天时间,但我设法解决了我自己的问题(没有打破 WF 的正常工作方式)。

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

最后,如果没有要安排的评估,我安排一个以字典为参数的最终活动,并且可以用它做任何想做的事情。它可以自行选择将最终结果返回到容器的 OutArgument。

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

于 2013-10-31T12:20:17.670 回答