工作流持久化应用开发全解析
立即解锁
发布时间: 2025-08-26 01:37:08 阅读量: 5 订阅数: 15 

### 工作流持久化应用开发全解析
#### 1. 工作流持久化基础
在工作流的运行过程中,`SqlWorkflowPersistenceService` 是一个关键的服务,它有一个 `LoadingInterval` 属性,可用于控制轮询间隔的频率。在多数场景下,当工作流处于空闲状态时,我们希望将其持久化并从内存中卸载。例如,当工作流等待接收外部事件时就可能进入空闲状态。卸载空闲的工作流是有意义的,因为这样可以释放宝贵的资源(如内存和工作流线程),让这些资源可被正在积极执行的工作流使用。而且由于我们无法确切知道工作流会空闲多久,所以通常卸载它会更高效。
若要启用空闲时卸载工作流的功能,在构造标准的 `SqlWorkflowPersistenceService` 时,必须将 `unloadOnIdle` 参数设置为 `true`。对于自定义的持久化服务,也需要在 `UnloadOnIdle` 方法中返回 `true`。
#### 2. 使用 SqlWorkflowPersistenceService
`WF` 包含 `SqlWorkflowPersistenceService` 类,该类实现了一个使用 `SQL Server` 作为持久存储的持久化服务。使用此服务是将持久化引入工作流的最简单方法。主要要求是必须安装一个版本的 `SQL Server`(`SQL Server 2000` 或更高版本),由于 `SQL Server Express` 现在可以免费获取,所以很容易满足这一要求。
使用 `SqlWorkflowPersistenceService` 的步骤如下:
1. 若尚未安装,安装一个版本的 `SQL Server`(`SQL Server 2000` 或更高版本),包括购买的完整版本(如 `SQL Server 2000` 或 `SQL Server 2005`)或免费版本(如 `SQL Server Express` 或 `Microsoft SQL Server Desktop Engine (MSDE)`)。
2. 创建一个用于工作流持久化的数据库,可以是一个仅包含持久化表的新数据库,也可以是应用程序已经使用的现有数据库。
3. 创建 `SqlWorkflowPersistenceService` 所需的数据库表、存储过程和其他对象。`WF` 包含创建这些对象的 `SQL` 脚本,只需针对目标数据库执行一次这些脚本。
4. 在宿主应用程序中,创建 `SqlWorkflowPersistenceService` 的实例,并将其作为核心服务添加到工作流运行时引擎中。这在工作流运行时初始化时只需执行一次。在 `SqlWorkflowPersistenceService` 的构造函数中,需要提供数据库连接字符串以及其他控制服务的参数,也可以使用 `App.config` 文件中的条目来加载此服务。
完成这些步骤后,工作流将根据前面所述的工作流运行时规则自动持久化。
以下是一个简单的示例应用程序,它是一个 `Windows Forms` 应用程序,允许启动多个工作流实例并监控它们的当前状态(如空闲、持久化、卸载、完成)。
#### 3. 准备持久化数据库
在开始开发演示应用程序之前,需要准备一个用于工作流持久化的数据库。
- 若尚未安装,安装一个版本的 `Microsoft SQL Server`。若没有完整的零售版本,可使用随 `Visual Studio 2008` 分发的 `SQL Server Express`。
- 安装 `SQL Server` 后,可按照相关步骤创建数据库并填充 `SqlWorkflowPersistenceService` 所需的对象。完成这些步骤后,一个名为 `WorkflowPersistence` 的本地数据库应包含工作流持久化所需的表和存储过程。演示应用程序假设这是数据库名称,并且它在 `SQL Server Express` 的本地实例(`localhost\SQLEXPRESS`)上可用。如果更改了数据库或服务器名称,需要相应调整示例代码。
#### 4. 实现本地服务
该应用程序需要能够引发工作流处理的两个不同事件,为此需要实现一个本地服务。具体步骤如下:
1. 使用 `Empty Workflow Project` 模板创建一个新项目,并将项目命名为 `SharedWorkflows`,这将创建一个可被 `Windows Forms` 演示应用程序引用的 `DLL` 程序集。
2. 定义本地服务的接口,在 `SharedWorkflows` 项目中添加一个新的 `C#` 接口,命名为 `IPersistenceDemo`,代码如下:
```csharp
using System;
using System.Workflow.Activities;
namespace SharedWorkflows
{
/// <summary>
/// Events exposed by the PersistenceDemoService
/// </summary>
[ExternalDataExchange]
public interface IPersistenceDemo
{
event EventHandler<ExternalDataEventArgs> ContinueReceived;
event EventHandler<ExternalDataEventArgs> StopReceived;
}
}
```
该接口使用 `ExternalDataExchangeAttribute` 进行修饰,以将其标识为本地服务接口,定义的两个事件都使用 `ExternalDataEventArgs` 作为事件参数,这是在工作流中处理这些事件的要求。
3. 在 `SharedWorkflows` 项目中添加一个新的 `C#` 类,命名为 `PersistenceDemoService`,它实现了 `IPersistenceDemo` 接口,代码如下:
```csharp
using System;
using System.Workflow.Activities;
namespace SharedWorkflows
{
/// <summary>
/// Implements events that are handled by workflow instances
/// </summary>
public class PersistenceDemoService : IPersistenceDemo
{
#region IPersistenceDemo Members
public event EventHandler<ExternalDataEventArgs> ContinueReceived;
public event EventHandler<ExternalDataEventArgs> StopReceived;
#endregion
#region Members used by the host application
/// <summary>
/// Raise the ContinueReceived event
/// </summary>
/// <param name="args"></param>
public void OnContinueReceived(ExternalDataEventArgs args)
{
if (ContinueReceived != null)
{
ContinueReceived(null, args);
}
}
/// <summary>
/// Raise the StopReceived event
/// </summary>
/// <param name="args"></param>
public void OnStopReceived(ExternalDataEventArgs args)
{
if (StopReceived != null)
{
StopReceived(null, args);
}
}
#endregion
}
}
```
除了实现两个 `IPersistenceDemo` 事件外,该服务还包含两个用于引发事件的方法,这些方法将由宿主应用程序调用,并且由于它们不是接口的一部分,所以工作流无法使用它们。
#### 5. 实现工作流
为了实现示例工作流,在 `SharedWorkflows` 项目中添加一个新的顺序工作流,命名为 `PersistenceDemoWorkflow`。工作流需要一个属性,该属性将被 `WhileActivity` 的条件引用,因此最好在开始工作流的可视化设计之前添加该属性。添加属性后的 `PersistenceDemoWorkflow.cs` 文件如下:
```csharp
using System;
using System.Workflow.Activities;
namespace SharedWorkflows
{
/// <summary>
/// A workflow that demonstrates the behavior of
/// persistence services
/// </summary>
public sealed partial class PersistenceDemoWorkflow :
SequentialWorkflowActivity
{
public Boolean IsComplete { get; set; }
public PersistenceDemoWorkflow()
{
InitializeComponent();
}
}
}
```
工作流的可视化设计相对简单:
1. 工作流从一个 `WhileActivity` 开始,其直接子活动为 `CompensatableSequenceActivity`。
2. 在 `CompensatableSequenceActivity` 下,有一个 `ListenActivity`,它有两个 `EventDrivenActivity` 分支。
3. 每个 `EventDrivenActivity` 包含一个 `HandleExternalEventActivity`,用于监听来自本地服务的事件。
具体实现步骤如下:
- 切换到可视化工作流设计器视图,将一个 `WhileActivity` 拖放到空工作流上。为 `WhileActivity` 添加一个声明性规则条件,将其 `ConditionName` 设置为 `checkIsComplete`,输入一个表达式来检查 `IsComplete` 工作流属性的值:`!this.IsComplete`。此条件使 `WhileActivity` 重复其子活动,直到 `IsComplete` 属性设置为 `true`。
- 添加一个 `CompensatableSequenceActivity` 作为 `WhileActivity` 的直接子活动。虽然此工作流的正确操作实际上不需要 `CompensatableSequenceActivity`,但添加它会在每次 `CompensatableSequenceActivity` 完成时调用额外的持久化服务方法。
- 在 `CompensatableSequenceActivity` 中添加一个 `ListenActivity`,并在每个 `EventDrivenActivity` 下添加一个 `HandleExternalEventActivity`。将两个 `HandleExternalEventActivity` 实例的 `InterfaceType` 设置为 `SharedWorkflows.IPersistenceDemo`。
- 将左侧的 `HandleExternalEventActivity` 实例重命名为 `handleContinueReceived`,并将 `EventName` 属性设置为 `ContinueReceived`,处理此事件无需添加任何代码,引发该事件就足以展示持久化服务在收到事件时的行为。
- 将右侧的 `HandleExternalEventActivity` 实例重命名为 `handleStopReceived`,并将 `EventName` 设置为 `StopReceived`。当收到此事件时,需要将 `IsComplete` 工作流属性设置为 `true`。为此,双击该活动以添加一个名为 `handleStopReceived_Invoked` 的 `Invoked` 事件处理程序。
完成可视化设计后,完整的 `PersistenceDemoWorkflow.cs` 文件如下:
```csharp
using System;
using System.Workflow.Activities;
namespace SharedWorkflows
{
/// <summary>
/// A workflow that demonstrates the behavior of
/// persistence services
/// </summary>
public sealed partial class PersistenceDemoWorkflow :
SequentialWorkflowActivity
{
public Boolean IsComplete { get; set; }
public PersistenceDemoWorkflow()
{
InitializeComponent();
}
private void handleStopReceived_Invoked(
object sender, ExternalDataEventArgs e)
{
//tell the WhileActivity to stop
IsComplete = true;
}
}
}
```
#### 6. 实现宿主应用程序
宿主应用程序是一个 `Windows Forms` 应用程序,允许启动并与多个工作流实例进行交互。表单将有一个 `DataGridView`,用于列出可用的工作流实例以及每个实例的状态消息。`DataGridView` 绑定到一个包含工作流实例 `ID` 和状态消息的对象集合。用户界面包含按钮,允许启动新的工作流实例或通过引发 `ContinueReceived` 或 `StopReceived` 事件与现有工作流实例进行交互。
以下是实现宿主应用程序的详细步骤:
1. **创建项目**:在当前解决方案中添加一个新的 `Windows Application` 项目,命名为 `PersistenceDemo`。由于该项目不是从工作流项目模板创建的,需要手动添加以下程序集的引用:
- `System.Workflow.Activities`
- `System.Workflow.ComponentModel`
- `System.Workflow.Runtime`
- `SharedWorkflows`
- `Bukovics.Workflow.Hosting`
其中,`SharedWorkflows` 和 `Bukovics.Workflow.Hosting` 是项目引用,`Bukovics.Workflow.Hosting` 项目包含一组协助托管任务的工作流管理器类。
2. **实现用于显示工作流状态的类**:在 `PersistenceDemo` 项目中添加一个新的 `C#` 类,命名为 `Workflow`,代码如下:
```csharp
using System;
namespace PersistenceDemo
{
/// <summary>
/// Used for display of workflow status in a DataGridView
/// </summary>
public class Workflow
{
public Guid InstanceId { get; set; }
public String StatusMessage { get; set; }
```
0
0
复制全文
相关推荐









