工作流服务主机可扩展性
.NET Framework 4.6.1 提供用于托管工作流服务的 WorkflowServiceHost 类。 当在托管应用程序或 Windows 服务中自承载工作流服务时,将使用该类。 同样,当使用 Internet 信息服务 (IIS) 或 Windows 进程激活服务 (WAS) 承载工作流服务时,也将使用该类。 通过 WorkflowServiceHost 类提供的扩展点,您可以添加自定义扩展、更改空闲行为以及承载非服务工作流(即不使用消息传递活动的工作流)。
工作流服务主机扩展
WorkflowServiceHost 包含一个 WorkflowExtensions 类型的 WorkflowInstanceExtensionManager 属性,该属性提供向 WorkflowServiceHost 添加扩展的方法。 使用 Add 方法可以为各工作流服务实例添加扩展。 从永久性存储中创建或加载工作流服务实例时,会调用指定的委托以创建新扩展。 使用 Add 方法可以为各工作流服务主机添加扩展,所有工作流服务实例共享一个扩展实例。
响应未经处理的异常
使用 WorkflowUnhandledExceptionBehavior 可以指定工作流服务中出现未经处理的异常时所采取的操作。 Action 属性指定下列 WorkflowUnhandledExceptionAction 值之一:
Abandon - 中止工作流服务实例。
AbandonAndSuspend - 回滚到最后保存的状态,并挂起工作流服务实例。 仅当已至少保存一次工作流时,才会发生此状况。 否则,将中止工作流实例。
Cancel - 取消实例。
Terminate - 终止实例。
可在代码中配置该行为,如下面的示例所示。
host.Description.Behaviors.Add(new WorkflowUnhandledExceptionBehavior { Action = WorkflowUnhandledExceptionAction.Abandon });
也可在配置文件中配置该行为,如下面的示例所示。
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<workflowUnhandledExceptionBehavior action="Abandon" />
</behavior>
</serviceBehaviors>
</behaviors>
承载非服务工作流
WorkflowServiceHost 可用于承载非服务工作流、未以 Receive 活动开头的工作流或未使用消息传递活动的工作流。 工作流服务通常以 Receive 活动开头。 如果 WorkflowServiceHost 在接收工作流服务的消息时未处于运行状态(或未保存),则会创建一个新的工作流服务实例。 如果工作流不以 Receive 活动开头,则无法通过发送消息来启动此工作流,因为没有用于接收消息的活动。 若要承载非服务工作流,请从 WorkflowHostingEndpoint 派生一个类,并重写 OnGetInstanceId、OnGetCreationContext 和 OnResolveBookmark。 如果您想提供首选实例 ID,请重写 OnGetInstanceId。 重写 OnGetCreationContext 可以创建自定义工作流创建上下文或填充现有 WorkflowCreationContext 的实例。 重写 OnResolveBookmark 可以从传入消息中手动提取书签。 如果重写此方法,则必须在其主体中调用 SendResponse,以便响应发送给 WorkflowHostingEndpoint 的消息。 如果不这样做,则可能会最终超过 MaxConcurrentCalls 限制。 在双向协定中,你也许能够检测到未能调用 SendResponse,因为客户端未能接收响应。 在单向协定中,您无法识别有关未能调用 SendResponse 的错误,直至超过 MaxConcurrentCalls 中止值之后,此时为时已晚。 若要创建非服务工作流的新实例,请声明一个用于定义创建新实例的操作的服务协定。 创建操作应使用 IDictionary<string, object> 传递所有必需的工作流参数。 该协定由 WorkflowHostingEndpoint 派生类隐式实现。 当承载工作流时,请通过调用 WorkflowHostingEndpoint 向主机添加 AddServiceEndpoint 派生类的实例,然后调用 Open。 若要创建工作流的实例,请创建所用服务协定类型的 ChannelFactory<TChannel>,并调用 CreateChannel。 然后,可调用在服务协定中定义的创建操作。