6

我将 WCF 服务设置为 PerCall

我想知道如何从客户端发送 Start 调用以启动长时间运行的进程,并发送 Cancel 命令以取消它

我的 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中应该如何启动和取消一个长时间运行的任务呢?

编辑:我将它作为 Windows 服务托管

4

2 回答 2

5

我将 WCF 服务设置为 PerCall

...这里的问题是,每次调用到达服务器时,它都被视为一个新请求。

是的,这正是你告诉它要做的事情。如果可以,只需更改为InstanceContextMode.PerSession; 然后你可以做你想做的事情(假设你是自托管的)。

如果你不能这样做,那么你将不得不开发一个更复杂的解决方案,就像@PeterRitchie 评论的那样。首先,您的主机:IIS 并非设计为独立于请求进行长时间运行的操作,因此我假设您是自托管的。接下来,您需要一种形式的令牌(如 GUID),它将充当长时间运行操作的标识符。您的Start方法将分配一个 GUID 并CancellationTokenSource开始操作,您的Stop方法将采用一个 GUID 并使用它来查找CancellationTokenSource和取消操作。您需要一个共享的(静态的、线程安全的)字典来充当查找。

如果您的主机IIS,那么您的解决方案会变得更加复杂...... :)

首先,您需要一个不在 IIS 中托管的后端。常见的选择是 Azure 辅助角色或 Win32 服务。接下来,您将需要一个可靠的通信机制:Azure 队列、MSMQ、WebSphere 等。然后您可以构建 WCF-over-IIS 服务,让该Start方法生成 GUID 标识符并将消息放入队列以开始处理. 该Stop方法采用 GUID 并将消息放在队列中以取消处理。所有其他逻辑都转移到后端服务。

于 2013-03-11T03:46:09.253 回答
2

根据您的询问方式,客户端似乎意识到请求的异步性质。

@StephenCleary 和@PeterRitchie 的观点非常好,但是您的第一步是重新执行您的服务/合同以正确实施异步服务,并添加将一些信息/句柄反馈回(给客户端)长期运行操作的方法。

该框架包含多个异步编程范例(已经:-))但是当涉及到 WCF 时,您有点回退到如何:实现异步服务操作

这将提供一些基础设施,但不一定能够自动取消操作。

严格谈论取消(因为这是您的问题):您将不得不扩展您的解决方案最终要取消的任何内容。至少你需要为你的服务“worker”添加必要的逻辑来监控和兑现取消令牌。

您可能会遇到的其他注意事项:取消返回结果;取消已成功完成的任务(在取消请求到来时,你们更新了 1,000,000 条记录);异常处理(基于任务的编程异常不会被抛出,而是捆绑在任务中,或者您用来描述正在进行的操作的任何其他“车辆”中)。

于 2013-03-11T05:09:12.397 回答