从客户取消长时间运行的任务交给WCF [英] Cancel a long running task over WCF from client
问题描述
我有一个WCF服务设置为PerCall
我想知道怎样才能从客户端发送一个开始呼叫开始长时间运行的进程,并发送取消命令,取消
我的WCF服务看起来像这样
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)
公共类服务1:IService1
{
CancellationTokenSource cancelToken =新CancellationTokenSource();
公共无效启动()
{
VAR计算= Task.Factory.StartNew(StartLongRunningTask,cancelToken.Token);
}
公共无效停止()
{
cancelToken.Cancel();
}
私人无效StartLongRunningTask()
{
//这里处理
}
}
我想这里的问题是,每一个电话打进来到服务器时,它会被视为一个新的请求。
那么我们应该如何开始和取消在WCF一个长期运行的任务来完成?
编辑:我收留了它作为Windows服务
我有一个WCF服务设置为PerCall
......这里的问题是,每一个电话打进来到服务器时,它会被视为一个新的请求。
是啊,这是你告诉它到底是什么做的。如果可以,只是改为 InstanceContextMode.PerSession
;那么你可以做你想做什么(假设你是自托管)。
如果你不能做到这一点,那么你就必须开发出更复杂的解决方案,像@PeterRitchie评论。首先,你的主机:IIS未设计为长期运行的操作相互独立的请求,所以我会假设你是自托管。接下来,你需要标记的形式(如GUID),将作为一个标识符长期运行的操作。你的启动
方法将分配一个GUID和 CancellationTokenSource
并开始操作,你的停止
方法将采取GUID,并用它来查找 CancellationTokenSource
键,取消操作。你需要一个共享(静态,线程)字典作为查询。
如果你的主机的是的IIS,那么你的解决方案变得更加复杂...:)
首先,你需要的不是在IIS托管后端。常见的选择是一个蓝色的工人角色或一个Win32服务。接下来,你需要一个可靠的通信机制:一个Azure的队列,MSMQ中,WebSphere,等等,那么你可以建立自己的WCF环比IIS服务有启动
方法生成一个GUID标识和删除消息队列,开始处理。该停止
方法将GUID并丢弃消息队列取消处理。所有其他逻辑被移动到后端服务。
I have a WCF service set to PerCall
I would like to know how I can send a Start call from the client to start a long running process, and send a Cancel command to cancel it
My WCF service looks something like this
[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
}
}
I guess the problem here is that, each time a call comes to the server, it's treated as a new request.
So how should starting and cancelling a long running task in WCF be done?
EDIT: I'm hosting it as a windows service
I have a WCF service set to PerCall
... the problem here is that, each time a call comes to the server, it's treated as a new request.
Yup, that's exactly what you're telling it to do. If you can, just change to InstanceContextMode.PerSession
; then you can do what you're trying to do (assuming you're self-hosting).
If you can't do this, then you'll have to develop a more complex solution like @PeterRitchie commented. First, your host: IIS is not designed to have long-running operations independent of requests, so I'll assume you're self-hosting. Next, you'll need a form of token (like a GUID) that will act as an identifier for a long-running operation. Your Start
method will allocate a GUID and CancellationTokenSource
and start the operation, and your Stop
method will take a GUID and use that to look up the CancellationTokenSource
and cancel the operation. You'll need a shared (static, threadsafe) dictionary to act as lookup.
If your host is IIS, then your solution gets more complex... :)
First, you'll need a backend that's not hosted in IIS. Common choices are an Azure worker role or a Win32 service. Next, you'll need a reliable communications mechanism: an Azure queue, MSMQ, WebSphere, etc. Then you can build your WCF-over-IIS service to have the Start
method generate a GUID identifier and drop a message on the queue to start processing. The Stop
method takes the GUID and drops a message on the queue to cancel processing. All other logic gets moved to the backend service.
这篇关于从客户取消长时间运行的任务交给WCF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!