我试图让Windows工作流程工作,并且我变得有点难住了。如何将参数传递给NativeActivity代码序列中的CodeActivity
我已经获得了一个工作流程,但现在我正在尝试做一些更复杂的事情:启动一个工作流程,其中每个活动本身都包含一个工作流程。 (图片类似于主程序启动“输入,逻辑和输出”活动,然后每个人都有附加活动,如“提示用户,获取输入等”)
我已经有它工作正常,从这里的例子(http://msdn.microsoft.com/en-us/magazine/gg535667.aspx),当我没有从主程序传递任何参数到activites。我的问题是,'变量'和'metadata.SetVariablesCollection'在NativeActivity中如何工作,以及如何将参数传递给低级活动?
这是我目前正在:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.Activities.Statements;
namespace Project1
{
internal class MainProgram
{
internal static void Main(string[] args)
{
try
{
var act = new SimpleSequence();
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Variables.Add(new Variable<string> ("stringArg", "TEXT"));
WorkflowInvoker.Invoke(act);
}
catch (Exception ex)
{
System.Console.WriteLine("EXCEPTION: {0}", ex);
}
}
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
protected override void Execute(CodeActivityContext context)
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
public class SimpleSequence : NativeActivity
{
Collection<Activity> activities;
Collection<Variable> variables;
Variable<int> current = new Variable<int> { Default = 0 };
public Collection<Activity> Activities
{
get
{
if (this.activities == null)
this.activities = new Collection<Activity>();
return this.activities;
}
set
{
this.activities = value;
}
}
public Collection<Variable> Variables
{
get
{
if (this.variables == null)
this.variables = new Collection<Variable>();
return this.variables;
}
set
{
this.variables = value;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetChildrenCollection(this.activities);
metadata.SetVariablesCollection(this.variables);
metadata.AddImplementationVariable(this.current);
}
protected override void Execute(NativeActivityContext context)
{
if (this.Activities.Count > 0)
context.ScheduleActivity(this.Activities[0], onChildComplete);
}
void onChildComplete(NativeActivityContext context, ActivityInstance completed)
{
int currentExecutingActivity = this.current.Get(context);
int next = currentExecutingActivity + 1;
if (next < this.Activities.Count)
{
context.ScheduleActivity(this.Activities[next], this.onChildComplete);
this.current.Set(context, next);
}
}
}
}
}
这最终引发了以下异常:
EXCEPTION: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors)
at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.WorkflowApplication.EnsureInitialized()
at System.Activities.WorkflowApplication.RunInstance(WorkflowApplication instance)
at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
at Project1.MainProgram.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ModelingProject1\Project1\MainProgram.cs:line 25
我知道,我只通过1个参数,但异常仍说我我缺少3个参数。我错过了如何正确地做到这一点。
当* SimpleSequence *中的下一个活动是* WriteSomeText *时,您也可以对* stringArg *进行硬编码,但这远不是最佳做法。 **硬编码**是一个信号。 – Joao
谢谢你,但我的问题就变成了,SimpleSequence中“Variables”变量的重点是什么?如果所有的代码活动在施工过程中都得到它们的参数,那么它的预期用途是什么? – Curtor
您必须将*变量 *作为常规方法中的局部变量,用于临时操作和保存数据**。在构建自定义活动时就像提供要使用的方法一样。您不希望用户在您的方法中触摸局部变量(无论是使用常规编程语言还是使用WF4本身)。对同一方法的任何输入都通过* InArgument *给出,它与方法中的参数声明相对应。 –
Joao