Cancel long-term task over WCF from client

I have a WCF service installed for PerCall

I would like to know how I can send a start call from a client to start a lengthy 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 assume that the problem is that every time a call comes to the server, it is processed as a new request.

So, how should you start and cancel a long-running task in WCF?

EDIT: I host it as a windows service

+4
source share
2 answers

I have a WCF service installed for PerCall

... the problem is that every time a call comes to the server, it is processed as a new request.

Yes, that’s exactly what you are saying. If you can, just change to InstanceContextMode.PerSession ; then you can do what you are trying to do (assuming that you own your own hosting).

If you cannot do this, you will have to develop a more complex solution, for example, @PeterRitchie. Firstly, your host: IIS is not designed for long-term operations that are independent of requests, so I assume that you own your own hosting. Next, you will need a token form (for example, a GUID) that will act as an identifier for a long-term operation. Your Start method will allocate the GUID and CancellationTokenSource and start the operation, and your Stop method will accept the GUID and use it to look up the CancellationTokenSource and cancel the operation. You will need a general (static, thread safe) dictionary to perform the search.

If your host is IIS, your decision becomes more complex ... :)

First you need a backend that is not hosted on IIS. A common choice is the Azure production agent role or the Win32 service. Then you need a reliable communication mechanism: Azure Queue, MSMQ, WebSphere, etc. You can then create your WCF-over-IIS service so that the Start method generates a GUID and deletes the message in the queue to begin processing. The Stop method accepts a GUID and discards the message in the queue to cancel processing. All other logic moves to the backend service.

+5
source

From what you requested, the client seems to know about the asynchronous nature of the request.

The signs of @StephenCleary and @PeterRitchie are excellent, but the first step is to re-execute your service / contract in order to correctly implement the asynchronous service and add funds to transfer some information / processing back (to the client) in the long term operation.

The Framework contains several paradigms for asynchronous programming (already :-)), but when it comes to WCF, you return to the Practical Guide. Implement Asynchronous Service Operation

This will provide some infrastructure, but not necessarily the ability to automatically cancel the operation.

Speaking strictly about cancellation (since this is your question): you will have to extend everything that your decision ends for cancellation. At a minimum, you need to add the necessary logic to your β€œworker” in order to control and comply with the cancellation token.

Other considerations you may encounter are: the result of the return from the cancellation; Cancel the task that was completed (that you updated 1,000,000 records at the time the cancellation request was received); exception handling (with task-based programming exceptions, it is not thrown away, but is included in the Task or some other "car" that you use to describe the current operation).

+2
source

All Articles