我有一个WCF服务设置为PerCall
我想知道我怎么可以从客户端发送启动呼叫开始长时间运行的进程,并发送取消命令取消
我的WCF服务看起来是这样的
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService1
{
CancellationTokenSource cancelToken = new CancellationTokenSource();
public void Start()
{
var compute = Task.Factory.StartNew(StartLongRunningTask, cancelToken.Token);
}
public void Stop()
{
cancelToken.Cancel();
}
private void StartLongRunningTask()
{
//process here
}
}
我想这里的问题是,每一个电话打进来到服务器时,它会被视为一个新的请求。
那么我们应该如何开始和取消在WCF长时间运行的任务来完成?
编辑:我收留了它作为一个窗口服务
我有一个WCF服务设置为PerCall
......这里的问题是,每一个电话打进来到服务器时,它会被视为一个新的请求。
是啊,这就是你告诉它该怎么做。 如果可以,只是改变InstanceContextMode.PerSession
; 那么你可以做你想做什么(假设你是自托管)。
如果你不能做到这一点,那么你就必须开发更复杂的解决方案就像@PeterRitchie评论。 首先,你的主机:IIS没有设计成具有长时间运行的操作独立请求的,所以我会假设你自托管。 接下来,你需要令牌的形式(如GUID),将作为长期运行的操作的标识符。 你Start
方法将分配一个GUID和CancellationTokenSource
并开始操作,你的Stop
方法将采取GUID并用它来查找该CancellationTokenSource
和取消操作。 你需要一个共享的(静态,线程)字典作为查找。
如果你的主机是 IIS,那么你的解决方案变得更加复杂... :)
首先,你需要的是不是托管在IIS后端。 常见的选择是一个蓝色的工人角色或Win32服务。 接下来,你需要一个可靠的通信机制:蔚蓝的队列,MSMQ中,WebSphere,等等,那么你可以建立自己的WCF环比IIS服务有Start
方法生成一个GUID标识符和队列删除消息开始处理。 该Stop
方法接受GUID和队列丢弃消息以取消处理。 所有其他逻辑被转移到后端服务。
从如何你问,客户端似乎也意识到请求的异步性质。
@StephenCleary和@ PeterRitchie的点是优秀的,但你的第一步是重新做你的服务/合同正确实现异步服务,并添加传送回(客户端)的一些信息的手段/处理对长时间运行的操作。
该框架包含了异步编程范式的几个(已:-)),但是当涉及到WCF,你还挺回落到如何:实现异步服务操作
这将提供一些基础设施,但不一定能自动取消操作的能力。
严格谈到消除(因为这是你的问题):你将不得不延长无论你的解决方案最终被注销。 在最低限度,你需要必要的逻辑添加到您的服务“工人”,以监测和兑现取消标记。
您可能会遇到的其他注意事项:从取消返回结果; 取消已经成功地完成任务(你用什么样的取消请求进来的时候1,000,000记录更新); 异常处理(基于任务的编程异常没有抛出,而是捆绑在任务,或任何其他的“车辆”你用来描述正在进行的操作)。