gpt4 book ai didi

workflow-foundation - 在 Workflow 4 RC 中调度运行时指定的 Activity

转载 作者:行者123 更新时间:2023-12-02 02:34:33 25 4
gpt4 key购买 nike

所以我有这个要求来启动在运行时提供给我的事件。为促进这一点,我设置了一个 WorkflowService,它以 Xaml 格式接收事件、整合它们并启动它们。

听起来很简单......

...这是我在 Xaml 中的 WorkflowService

<Activity 
x:Class="Workflow.Services.WorkflowService.WorkflowService"
...
xmlns:local1="clr-namespace:Workflow.Activities" >
<Sequence sap:VirtualizedContainerService.HintSize="277,272">
<Sequence.Variables>
<Variable x:TypeArguments="local:Workflow" Name="Workflow" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<p:Receive CanCreateInstance="True" DisplayName="ReceiveSubmitWorkflow" sap:VirtualizedContainerService.HintSize="255,86" OperationName="SubmitWorkflow" ServiceContractName="IWorkflowService">
<p:ReceiveParametersContent>
<OutArgument x:TypeArguments="local:Workflow" x:Key="workflow">[Workflow]</OutArgument>
</p:ReceiveParametersContent>
</p:Receive>
<local1:InvokeActivity Activity="[ActivityXamlServices.Load(New System.IO.StringReader(Workflow.Xaml))]" sap:VirtualizedContainerService.HintSize="255,22" />
</Sequence>
</Activity>

...除了重复使用“工作流程”外,它非常简单。其实就是一个SequenceReceive和 [当前] 一个名为 InvokeActivity 的自定义事件.稍后再讲。

Receive Activity 接受自定义类型,

[DataContract]
public class Workflow
{
[DataMember]
public string Xaml { get; set; }
}

其中包含一个字符串,其内容将被解释为 Xaml。您可以看到随后将此 Xaml 转换为事件并将其传递的 VB 表达式。

现在第二位,自定义 InvokeActivity这是我有问题的地方。

第一个问题:

1) 给定一个任意任务,在运行时提供 [如上所述] 是否可以使用 WF4RC 随附的开箱即用的事件来启动此事件?我是相当新的,并且认为我在浏览 API 和现有文档方面做得很好,但也可以问 :)

第二个:

2) 我第一次尝试实现自定义 InvokeActivity看起来像这样

public sealed class InvokeActivity : NativeActivity
{
private static readonly ILog _log =
LogManager.GetLogger (typeof (InvokeActivity));

public InArgument<Activity> Activity { get; set; }

public InvokeActivity ()
{
_log.DebugFormat ("Instantiated.");
}

protected override void Execute (NativeActivityContext context)
{
Activity activity = Activity.Get (context);

_log.DebugFormat ("Scheduling activity [{0}]...", activity.DisplayName);

// throws exception to lack of metadata! :(
ActivityInstance instance =
context.ScheduleActivity (activity, OnComplete, OnFault);

_log.DebugFormat (
"Scheduled activity [{0}] with instance id [{1}].",
activity.DisplayName,
instance.Id);
}

protected override void CacheMetadata (NativeActivityMetadata metadata)
{
// how does one add InArgument<T> to metadata? not easily
// is my first guess
base.CacheMetadata (metadata);
}

// private methods

private void OnComplete (
NativeActivityContext context,
ActivityInstance instance)
{
_log.DebugFormat (
"Scheduled activity [{0}] with instance id [{1}] has [{2}].",
instance.Activity.DisplayName,
instance.Id,
instance.State);
}

private void OnFault (
NativeActivityFaultContext context,
Exception exception,
ActivityInstance instance)
{
_log.ErrorFormat (
@"Scheduled activity [{0}] with instance id [{1}] has faulted in state [{2}]
{3}",
instance.Activity.DisplayName,
instance.Id,
instance.State,
exception.ToStringFullStackTrace ());
}
}

它尝试在当前上下文中安排指定的事件。然而,不幸的是,这失败了。当我尝试安排所述事件时,运行时返回以下异常

The provided activity was not part of this workflow definition when its metadata was being processed. The problematic activity named 'DynamicActivity' was provided by the activity named 'InvokeActivity'.

是的,所以在运行时提供的“动态”Activity 不是 InvokeActivity 的成员元数据。 Googled遇到了this .无法弄清楚如何指定 InArgument<Activity>到元数据缓存,所以我的第二个问题自然是如何解决这个问题?不建议使用 context.ScheduleActivity (...)以这种方式?

第三次也是最后一次,

3) 我暂时选择了这个[更简单]的解决方案,

public sealed class InvokeActivity : NativeActivity
{
private static readonly ILog _log =
LogManager.GetLogger (typeof (InvokeActivity));

public InArgument<Activity> Activity { get; set; }

public InvokeActivity ()
{
_log.DebugFormat ("Instantiated.");
}

protected override void Execute (NativeActivityContext context)
{
Activity activity = Activity.Get (context);

_log.DebugFormat ("Invoking activity [{0}] ...", activity.DisplayName);

// synchronous execution ... a little less than ideal, this
// seems heavy handed, and not entirely semantic-equivalent
// to what i want. i really want to invoke this runtime
// activity as if it were one of my own, not a separate
// process - wrong mentality?
WorkflowInvoker.Invoke (activity);

_log.DebugFormat ("Invoked activity [{0}].", activity.DisplayName);
}

}

它只是在它自己的运行时实例中同步调用指定的任务 [使用 WF4 白话当然是有问题的]。最后,我想利用 WF 的跟踪和可能的持久性设施。所以我的第三个也是最后一个问题是,就我想做什么 [即启动从客户端应用程序入站的任意工作流] 而言,这是首选方法吗?

好的,提前感谢您的时间和考虑:)

最佳答案

The provided activity was not part of this workflow definition when its metadata was being >processed. The problematic activity named 'DynamicActivity' was provided by the activity >named 'InvokeActivity'.

Workflow 4.0 只允许您在开始执行之前安排属于树的一部分的 child 。

此规则可能存在,因为如此构建的树可由多个工作流实例重复使用。如果实例 A 在实例 B 仍在运行时修改树,结果会让运行时团队非常头疼。

在实践中,这意味着您可以在运行时动态安排子进程来做您想做的事情的唯一方法是启动一个全新的工作流(并可选择等待它完成)。

关于workflow-foundation - 在 Workflow 4 RC 中调度运行时指定的 Activity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2374911/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com