我有一个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活动仅在父执行方法返回后执行。将它添加为实现子元素不起作用(它不能用作实现子元素,因为它应该评估包含父元素外部变量的表达式。)
如何克服这个问题并在执行环境中执行?
答案 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。
我之前未能理解的是,即使调度发生在实例化活动的执行之后,回调也会在控制权返回到主机工作流应用程序之前运行,并且在那个空间中我可以工作。