无状态的工作流服务每次调用服务都会创建一个新的工作流实例。无状态的服务在客户端和服务器端不需要上下文交换。而有状态的则需要,
在下面的例子中我们开发一个有状态的工作流服务,我们使用WSHttpContextBinding。
1.首先定义IAddStatefulService接口,代码如下:
namespace CaryWFLib { [ServiceContract] public interface IAddStatefulService { [OperationContract] void StartWorkflow(); [OperationContract] Double Add(Double num1, Double num2); [OperationContract] void StopWorkflow(); } }
2.然后我们设计我们的工作流,我们这次使用状态机工作流,如下图:
ReceiveActivity的使用可以参考工作流服务Workflow Service(1):ReceiveActivity这篇文章。
3.我们在IIS中宿主该工作流服务,完成后可以使用如下代码进行测试。
namespace AddStatefulServiceConsole { class Program { static void Main(string[] args) { AddStatefulServiceClient client1 = new AddStatefulServiceClient(); AddStatefulServiceClient client2 = new AddStatefulServiceClient(); Console.WriteLine("Server endpoint: {0}",client1.Endpoint.Address.ToString()); client1.StartWorkflow(); client2.StartWorkflow(); double result; result = client1.Add(1, 2); Console.WriteLine("Client1 计算的结果为: {0}", result); result = client2.Add(1,2); Console.WriteLine("Client2 计算的结果为: {0}", result); client1.StopWorkflow(); client1.Close(); client2.StopWorkflow(); client2.Close(); Console.WriteLine("Press any key to exit"); Console.ReadKey(); } } }
4.除了使用上面的方法来调用工作流服务,我们还可是使用WF本身提供的SendActivity来调用工作流服务,我们新建一个顺序工作流控制
台项目。在工作流设计器中我们拖入SendActivity,如下图:
我们还是像使用ReceiveActivity同样的方式来设置SendActivity的ServiceOperationInfo属性,ChannelToken是每一个SendActivity必须要正确的
设置属性,通道令牌用来指定通道名称、通道范围和用于建立通道的终结点配置名称。Name属性为AddChannel,EndpointName属性为AddEndpoint,
该属性与App.config中的相对应,还有OwnerActivityName属性为SendWorkflow。OwnerActivityName和Nam属性决定WCF使用的通信通道,
我们的例子中所有的SendActivity的ChannelToken都是同样的设置,保证所有的服务操作都使用相同的通道,当相同的通道被使用,服务消息将会
在同一个工作流服务实例交换。
App.config如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpContextBinding> <binding name="AddBindingConfig" openTimeout="00:00:30" sendTimeout="00:00:30" receiveTimeout="00:00:30" closeTimeout="00:00:30" > </binding> </wsHttpContextBinding> </bindings> <client> <endpoint address="http://localhost/CaryWFWCF/AddStatefulServiceWorkflow.svc" binding="WSHttpContextBinding" bindingConfiguration="AddBindingConfig" contract="CaryWFLib.IAddStatefulService" name="AddEndpoint"> </endpoint> </client> </system.serviceModel> </configuration>
5.测试程序如下:
namespace WorkflowConsoleSend { class Program { static void Main(string[] args) { using (WorkflowRuntime workflowRuntime = new WorkflowRuntime()) { AutoResetEvent waitHandle = new AutoResetEvent(false); workflowRuntime.WorkflowCompleted += delegate( object sender, WorkflowCompletedEventArgs e) { Console.WriteLine("result is {0}", e.OutputParameters["Result"]); waitHandle.Set(); }; workflowRuntime.WorkflowTerminated += delegate( object sender, WorkflowTerminatedEventArgs e) { Console.WriteLine(e.Exception.Message); waitHandle.Set(); }; //create channel manager service in order to manage and //reuse WCF channels. workflowRuntime.AddService(new ChannelManagerService()); Dictionary<String, Object> parameters = new Dictionary<string, object>(); parameters.Add("Num1", 1); parameters.Add("Num2", 2); WorkflowInstance instance = workflowRuntime.CreateWorkflow( typeof(WorkflowConsoleSend.SendWorkflow), parameters); instance.Start(); waitHandle.WaitOne(); Console.WriteLine("Press any key to exit"); Console.ReadKey(); } } } }
ChannelManagerService 负责根据在活动 ChannelToken 中定义的通道令牌,创建 SendActivity 的通道。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器