惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
N
News | PayPal Newsroom
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
博客园 - Franky
SecWiki News
SecWiki News
Recent Announcements
Recent Announcements
T
Troy Hunt's Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
S
Security Affairs
博客园 - 司徒正美
S
Schneier on Security
I
InfoQ
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
腾讯CDC
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
Cloudbric
Cloudbric
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
Vulnerabilities – Threatpost
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
Schneier on Security
Schneier on Security
O
OpenAI News
K
Kaspersky official blog

博客园 - gotolovo

导出csv 导出excel 正则学习电话匹配 logmanager des 加密 解密 - gotolovo c# 发送邮件 工作流学习过程-事务 工作流学习过程-状态机 蛋疼的viewstate 工作流学习过程-持久化服务 工作流学习过程-使用关联 工作流学习过程-本地服务之事件处理 工作流学习过程-验证活动 工作流学习过程-自定义活动 工作流学习过程-开篇 基本的几个排序算法 关于sql中时间的格式转换 数据行变列 请编程遍历页面上所有TextBox控件并给它赋值为空
工作流学习过程-本地服务之调用方法
gotolovo · 2010-10-25 · via 博客园 - gotolovo

先来看看工作流如何调用服务
基础代码如下:

一个实体类用于传递参数

代码

public class Account
{
public int AccountId { get; set; }
public double AcccountAmount { get; set; }
public double AccountBalance { get; set; }public override string ToString()
{
return string.Format("AccountId:{0}\tAcccountAmount:{1}",AccountId.ToString(),AcccountAmount.ToString());
}
}

接口及服务代码:

代码

public interface ILocalService
{
Account Calculator(Account Account);
}
public class LocalService:ILocalService
{
#region ILocalService 成员public Account Calculator(Account account)
{
return innerCalculator(account);
}
#endregionprivate Account innerCalculator(Account account)
{
account.AcccountAmount
= account.AcccountAmount + account.AccountBalance;
Console.WriteLine(account);
return account;
}
}

新建一工作流
定义两个绑定属性分别为接受和返回的
加一个CodeActivity事件为codeActivity1_ExecuteCode

具体代码如下:

代码

public sealed partial class LocalServiceActivity : SequentialWorkflowActivity
{
public static DependencyProperty LocalServiceValueProperty = DependencyProperty.Register("LocalServiceValue", typeof(Account), typeof(LocalServiceActivity));

[DescriptionAttribute(

"LocalServiceValue")]
[CategoryAttribute(
"LocalServiceValue Category")]
[BrowsableAttribute(
true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public Account InputValue
{
get
{
return ((Account)(base.GetValue(LocalServiceActivity.LocalServiceValueProperty)));
}
set
{
base.SetValue(LocalServiceActivity.LocalServiceValueProperty, value);
}
}
public static DependencyProperty OutputValueProperty = DependencyProperty.Register("OutputValue", typeof(Account), typeof(LocalServiceActivity));

[DescriptionAttribute(

"OutputValue")]
[CategoryAttribute(
"OutputValue Category")]
[BrowsableAttribute(
true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public Account OutputValue
{
get
{
return ((Account)(base.GetValue(LocalServiceActivity.OutputValueProperty)));
}
set
{
base.SetValue(LocalServiceActivity.OutputValueProperty, value);
}
}
public LocalServiceActivity()
{
InitializeComponent();
}
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
ILocalService service
= new LocalService();
OutputValue
= service.Calculator(InputValue);
}
}

新建宿主程序。执行代码

代码

private static void LocalServiceTest1()
{
BaseWorkflow.Loaclservice.Account outaccount
= new BaseWorkflow.Loaclservice.Account();using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle
= new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e) {
outaccount
= (BaseWorkflow.Loaclservice.Account)(e.OutputParameters["OutputValue"]);
waitHandle.Set(); };
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e) { waitHandle.Set(); };

Dictionary

<string, object> paras = new Dictionary<string, object>();

BaseWorkflow.Loaclservice.Account account

= new BaseWorkflow.Loaclservice.Account() { AccountId = 1001, AcccountAmount = 200,AccountBalance=50 };

paras.Add(

"InputValue", account);

WorkflowInstance instance;
instance

= workflowRuntime.CreateWorkflow(typeof(LocalServiceActivity), paras);
instance.Start();
waitHandle.WaitOne();

Console.Write(outaccount);

Console.ReadKey();
}
}

运行可观察到 服务确实被工作流调用了。而且最后结果也可以返回给宿主
那么本地服务是什么呢?
WF提供了一种服务,叫做Local Service也可以叫做Data exchange service。主要是实现工作流和宿主程序之间的通信,使工作流能够使用方法和事件通过消息与外部系统交互。 事件用于将数据发送到工作流,而工作流使用方法将数据发送到主机应用程序。 通过事件与工作流进行通信的功能提供了一种将数据发送到工作流的异步方式。
下面首先说说如何开发一个本地服务:
1.使用C#的接口定义服务契约,在接口中定义你方法和事件。并使用[ExternalDataExchangeAttribute]装饰该接口,用于说明这是一个本地服务的接口。
2.开发一个实现了该接口的类,用于实现你的逻辑。

3.创建一个工作流实例,并将该本地服务添加到工作流引擎中去:实现方法

ExternalDataExchangeService dataservice = new ExternalDataExchangeService();
workflowRuntime.AddService(dataservice);
YourService yourService
= new YourService();
dataservice.AddService(yourService);

1). 先将ExternalDataExchangeService服务对象添加到引擎。
2).再将我们自己开发的服务绑定到ExternalDataExchangeService服务中。接口具体代码

[ExternalDataExchange]
public interface ILocalService
{
Account Calculator(Account Account);
}
服务代码
public class LocalService:ILocalService
{
#region ILocalService 成员public Account Calculator(Account account)
{
return innerCalculator(account);
}
#endregionprivate Account innerCalculator(Account account)
{
account.AcccountAmount
= account.AcccountAmount + account.AccountBalance;
Console.WriteLine(account);
return account;
}
}

宿主代码

代码

private static void LocalServiceTest2()
{
BaseWorkflow.Loaclservice.Account outaccount
= new BaseWorkflow.Loaclservice.Account();using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle
= new AutoResetEvent(false);

ExternalDataExchangeService dataservice

= new ExternalDataExchangeService();
workflowRuntime.AddService(dataservice);
LocalService accountService
= new LocalService();
dataservice.AddService(accountService);

workflowRuntime.WorkflowCompleted

+= delegate(object sender, WorkflowCompletedEventArgs e)
{
outaccount
= (BaseWorkflow.Loaclservice.Account)(e.OutputParameters["OutputValue"]);
waitHandle.Set();
};
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e) { waitHandle.Set(); };

Dictionary

<string, object> paras = new Dictionary<string, object>();

BaseWorkflow.Loaclservice.Account account

= new BaseWorkflow.Loaclservice.Account() { AccountId = 1001, AcccountAmount = 200, AccountBalance = 50 };

paras.Add(

"InputValue", account);

WorkflowInstance instance;
instance

= workflowRuntime.CreateWorkflow(typeof(LocalServiceActivity), paras);
instance.Start();
waitHandle.WaitOne();

Console.Write(outaccount);

Console.ReadKey();
}
}


服务定义好了,我们下面就要在工作流中条用该服务,我们有几种方式:
方法一:
Activity有一个方法OnActivityExecutionContextLoad(),我们通过该

的IServiceProvider的GetService方法来获取本地服务,代码如下:

代码

protected override void OnActivityExecutionContextLoad(IServiceProvider provider)
{
base.OnActivityExecutionContextLoad(provider);
service
= provider.GetService(typeof(ILocalService)) as ILocalService;
if (service == null)
{
throw new InvalidOperationException("Unable to retrieve ILocalService from runtime");
}
}


OnActivityExecutionContextLoad 表示活动正加载到工作流运行时

方法二:配置文件方式
方法三:使用自定义活动 

代码

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
service
= executionContext.GetService(typeof(ILocalService)) as ILocalService;
if (service == null)
{
throw new InvalidOperationException("Unable to retrieve ILocalService from runtime");
}
OutputValue
=service.Calculator(InputValue);
return base.Execute(executionContext);
}

方法四:使用CallExternalMethodActivity
interfaceType为接口名称,MethodName为调用的方法名称,该方法如何有参数则属性窗口中将会列出以供选择,返回值亦是如此,
需要指出的是。这种情况下。参数类型必须为可序列化的
其它情况不是也可以的~