WF4提供了强大的持久化模型,之前我也翻译了一篇文章描述了WF4中持久化的一些知识,[译]Windows Workflow Foundation 4 和持久性。
我会系统的介绍下WF4中的持久化服务。WF4提供了一个抽象类InstanceStrore,表示逻辑上的工作流实例的容器,还有一些和持久化相关的类如LoadWorkflowCommand,SaveWorkflowCommand等,具体的实现我们可以从InstanceStore类继承来开发自己的Persistence Provider。WF4已经默认给我们实现好了一个基于SQL的持久化实现,对应于SqlWorkflowInstanceStore类。下面是这两个类的继承关系:
下面是关于SqlWorkflowInstanceStore类属性的一些说明:
Instance Encoding Option:指定保存到持久化存储的压缩算法,可选值为GZip和None。
Instance Completion Action:指定当工作流实例完成后的操作(是否删除持久化存储中的数据),有两个值DeleteAll(默认),DeleteNothing。
Instance Locked Exception Action:当发生InstanceLockedException时发生的操作,该异常发生在当他要去锁定已经被其他服务宿主锁定的实例时。有几个值NoRetry,BasicRetry,AggressiveRetry。
Host Lock Renewal Period:服务宿主在指定时间内必须更新锁定时间周期。
下面就简单说明下如何使用SqlWorkflowInstanceStore来完成工作流的持久化操作,在开始这个例子前需要先建立持久化数据库。
1. 定义一个ReadLine自定义活动,如下:
public sealed class ReadLine : NativeActivity<string>
{
public ReadLine()
{
}
public InArgument<string> BookmarkName { get; set; }
protected override bool CanInduceIdle
{
get
{
return true;
}
}
protected override void Execute(NativeActivityContext context)
{
string name = this.BookmarkName.Get(context);
if (name == null)
{
throw new ArgumentException(string.Format("ReadLine {0}: BookmarkName cannot be null", this.DisplayName), "BookmarkName");
}
context.CreateBookmark(name, new BookmarkCallback(OnReadComplete));
}
void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state)
{
string input = state as string;
if (input == null)
{
throw new ArgumentException(string.Format("ReadLine {0}: ReadLine must be resumed with a non-null string"), "state");
}
context.SetValue(base.Result, input);
}
}
}
2.工作流中我们使用ReadLine等待输入,设计如下:
3. 宿主程序如下:
namespace CaryPersisten
{
class Program
{
static InstanceStore instanceStore;
static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);
static Guid id;
static void
{
instanceStore =new SqlWorkflowInstanceStore("server=.;database=SampleInstanceStore;uid=sa;pwd=123456");
InstanceView view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
instanceStore.DefaultInstanceOwner = view.InstanceOwner;
WorkflowApplication application = new WorkflowApplication(new Workflow1());
application.InstanceStore = instanceStore;
application.PersistableIdle = (e) =>
{
return PersistableIdleAction.Unload;
};
application.Unloaded = (e) =>
{
instanceUnloaded.Set();
};
application.Persist();
id = application.Id;
application.Run();
instanceUnloaded.WaitOne();
string input = Console.ReadLine();
WorkflowApplication application1 = new WorkflowApplication(new Workflow1());
application1.InstanceStore = instanceStore;
application1.Completed = (workflowApplicationCompletedEventArgs) =>
{
Console.WriteLine("\nWorkflowApplication has Completed in the {0} state.", workflowApplicationCompletedEventArgs.CompletionState);
};
application1.Unloaded = (workflowApplicationEventArgs) =>
{
Console.WriteLine("WorkflowApplication has Unloaded\n");
instanceUnloaded.Set();
};
application1.Load(id);
application1.ResumeBookmark("nabookmark", input);
instanceUnloaded.WaitOne();
Console.ReadLine();
}
}
}
4.在宿主程序中首先我们创建SqlWorkflowInstanceStore的实例,并将WorkflowApplicaiton的InstanceStore属性设置为该实例来指定使用的持久化存储。我们在自定义活动创建了书签,创建书签会让工作流变为idle状态进行持久化操作,工作流持久化后我们可以看到数据库的信息如下:
接收到输入后恢复书签,并将持久化数据库中的工作流实例装载到内存中继续运行工作流。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2008-12-09 MOSS程序中如何发Mail?