Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
905 views
in Technique[技术] by (71.8m points)

c# - How to cancel an async WCF call?

I have been trying some time to find out how to implement WCF call cancellation based on the new .NET 4.5 CancellationToken mechanism. All the samples I found are not WCF based, and do not cross the service boundary.

My service :

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService
{   
    public void LongOperation()
    {
        // do stuff that takes ages...
        // please cancel me!
    }
}

My Client (Desktop App):

Using an auto generated proxy :

private async void DoLongRunningTaskAsync()
{
    var asyncTask = _myService.LongOperationAsync();
    await asyncTask;
}

How do I cancel this task? Please provide a concrete example applicable to WCF on .NET 4.5+

EDIT:

The answers below seem to indicate that its impossible for technical reasons. So, imagine, I make my service ContextMode=Session, then set a static variable (in a separate service call) called cancellationPending=true, my original call is still running at this stage, and it periodically checks that variable. Would I still not be able to cancel? would it still be impossible? if so, why?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In two words - this is impossible.

If you understand what WCF call is by its nature, it becomes obvious.

Looking on your example, what we see generally: Two separate machine A and B, connected via networks. On machine A you have some component which listen a socket, and when it gets a command it starts synchronous long computation RemoteCall().

On machine B you have a client which has two autogenerated methods in fact

BeginRemoteCall->IAsyncResult + EndRemoteCall(IAsyncResult).

New Task based version of asynchronous call (aka RemoteCallAsync()->Task) by the nature is absolutely the same, and you can always create your own task using TaskFactory.FromAsync(BeginRemoteCall,EndRemoteCall)->Task

When you call BeginRemoteCall on the client, you send the command to the second machine "please start computation", and then you add a callback, which will be called, when calculation is done and results came. Internally this async implementation uses I/O completion ports and allows your client to be non-blocking.

But there is no way to cancel an operation on the server side, if it is already started. You may not be interested in results, you may ignore your callback, but the computation on the server side will be finished anyway.

That's it


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...