I want to implement a WCF service that responds immediately to the caller, but queues up an asynchronous job to be handled later. What is the best way to go about doing this? I've read the MSDN article on how to implement an asynchronous service operation, but that solution seems to still require the task to finish before responding to the caller.
There are many ways to accomplish this depending what you want to do and what technologies you are using (e.g. Unless you are using silverlight, you may not need to have your app call the service asynchronously) The most straight forward way to achieve your goal would be to have your service method start up a thread to perform the bulk of the processing and return immediately.
Another would be to create some kind of request (e.g. Create an entry in a datastore of some kind) and return. Another process (e.g. A windows service, etc.) could then pick up the request and perform the processing.
Any WCF service can be made asynchronous -
One of the nice things about WCF is you can write a service synchronously. When you add a ServiceReference in the client, you have the option of generating asynchronous methods.
This will automatically make the service call asynchronous. The service will return when it's done, but the client will get two methods - BeginXXX and EndXXX, as well as XXXAsync + an XXXCompleted event, either of which allows for completely asynchronous operation.
Related
Am doing some time consuming File operation in WCF web service, so until this call completed i cant make any other service calls from my application.
So i planned use the TPL
Task.Factory.StartNew(() =>
{
CheckFileandCopy(path,fileName);
});
it works, and return true, but the problem is, the completed event doesnt have the actual result, coz the process is running in seperate thread, so am not getting the actual complete event, how i can return the complete event once the task is done, and also how i can make concurrent call when the time consuming method is invoked
You have basically two options:
Do asynchronous calls client side. If you generate a proxy including async methods (for example see this msdn page this would be easy.
Make things asynchronous, server side. This is similar what you did in your example. Only thing missing is the callback with the actual result. For this you can use the duplex scenario where the client is able to receive a call from the service just as if the client is also a service. Note that not all scenario's/bindings support this.
In both cases reading through this msdn article on sessions and concurrency may help with understanding things.
I am trying to create a XAMLX service that I can fire and forget.
But how can I do something like that with a XAMLX? I have no access to the Contract Interface to add the [OneWay] attribute.
I thought that if I did something like
and put the response before the rest of the activities, the service would return at that point but it didn't. It returns only after the whole workflow is completed.
IS it possible to make the service return at that point and than continue with the processing. the other activities would not affect the returned value of the service.
Is it possible to create a fire and forget XAMLX service
Can I somehow make the client fire a normal service as oneWay, if the previous 2 points are not possible?
If you want one-way processing your Receive activity should not have any corresponding SendReply activity.
The reason the response isn't send immediately is the way the workflow scheduler works internally where it waits for the workflow to go idle. Nothing much you can do about the scheduler but if you add a Delay below the SendResponse with a duration of 1 millisecond.
As Ladislav said, remove the SendResponse and you get a one way message.
Not quite sure what you want with fire and forget. If you start a workflow service it will keep on running even if you don't send any more WCF requests to it. Even if it is long running or does other async work. No problems there.
I have an existing WCF service that I now need to have consume an external WCF callback (aka duplex) service. The duplex service is by its nature asynchronous and yet I need to keep my original WCF service synchronous. Is there a well known pattern to do this? What are the most important pitfalls I need to watch out for?
My current intention is to invoke the duplex service and then wait for a ManualResetEvent to be raised. When the callback is called by the duplex, it would reset the event and make the waiting operation resume and complete its work.
Yes, I'd go this way too. Pay attention to how you control these events' lifetime. Seems like you'll need to pass some id to the duplex service so that, when callback arrives, this id could be resolved into the original ManualResetEvent.
In my current web project, we perform a ClientFactory.CreateChannel for every method call to a remote service.
Is this really necessary?
What is the best practice?
This depends to some extent what your requirements are. Opening a channel is expensive, relatively speaking. Best practice is to have the class that is doing the remote calls implement IDisposable, it should make a call to ClientFactory.CreateChannel once, use the channels in all the method calls, and close the channel when the Dispose method is called. That said, if the time between the calls to methods that call to a remote service is long (longer then the default idle timeout on the channel which is 10 minutes) then doing a ClientFactory.CreateChannel isn't particularly harmful, but I would say it would still be better to go the IDisposable route and encapsulate use of the class with the 'using' keyword
creating a new channel for each method call comes in bad practice "generally".
For Duplex WCF Service
creating a single channel and using it until there is no need to communicate with server anymore/ or that channel gets closed.
After creating the channel, before making any call to server, its recommended to check channel's state (Error, opening, closed).
Registering the channel closed/Error events is recommended to get to know immmediatley when it occurs. so you can take necessary actions or/and create the channel again with same object channel object reference.
For Normal WCF service
Create the proxy pattern, to create channel/ to re-use/ re create, error handling and disposing. set the appropiate inactivity timeout along with WCF client's proxy appropiate configuration which suits best with your solution.
Always Load test!!!!
In the project I'm currently working we're using WCF.
Company policy forces us to use async calls and the reason should be security.
I've asked why this is so much more secure but I don't get clear answers.
Can someone explain why this is so much secure?
They are not. The same security (authentication, encryption) mechanisms and considerations apply whether a call blocks until it gets a response or it uses a callback.
The only way someone may be confused into thinking that asynch calls are more "safe/secure", is they think that unhandled WCF exceptions will not bring down the main thread if they are asynchronous, as they will be raised inside the callback.
In this case, I would advice extreme caution when approaching the owner of this policy to avoid career-limiting consequences. Some people can get emotionally attached to their policies.
There is no point why an async call will be more secure than a sync call. I think you should talk to the owner of the policy for the same.
No they are not more or less secure than synchronous calls. The only difference is the client waits for a response on synchronous calls, whereas on async it is notified of a response.
Are they coming from the angle that synchronous calls leave the connection open longer or something?
Just exposing a WCF operation using an async signature (BeginBlah/EndBlah) doesn't actually affect the exposed operation at all. When you view the meta data, an operation like
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginSomething(AsyncCallback, object)
void EndSomething(IAsyncResult)
...actually still ends up being represented as an operation called 'Something'. And actually this is one of the nice things about WCF: the client and server can differ in whether they choose to implement/consume an operation syncronously.
So if you are using generating WCF proxies (eg through Add Service Reference) then you will get syncronous versions of each operation whether they are implemented asyncronously or not unless you tick the little checkbox to generate the async overloads. And when you do you then get async versions of operations that might only be declared syncronously on the server.
All WCF is doing is, on both the client and server, giving you a choice about your threading model: do you want WCF to wait for the result, or are you going to signal it that you've finished. How the actual transport connection is managed is - to the best of my knowlege - totally unaffected. eg: For a NetTcpBinding the socket still stays open for the duration of the call, either way.
So, to get to the point, I really struggle to imagine how this could possibly make any difference to the security envelope of a WCF service. If a service is exposed using an async pattern, and is genuinely implemented in an async way (async for outbound IO, or queues work via the thread pool or something) then there's probably an argument that it would be harder to DOS the service (by exhausting the pool of WCF IO threads), but that'd be about it.
See Syncronous and Asyncronous Operations in MSDN
NB: If you are sharing the contract interface between the client and server then obviously the syncronisity of the two ends match (because they are both using the same interface type), but that's just a limitation of using a shared interface. If you made another equivilent interface, differing only by the async pattern, you could still create a ChannelFactory against it just fine.
I agree with the other answers - definitely not more secure.
Fire up Fiddler and watch a synchronous request vs. an asynchronous request. You'll basically see the same type of traffic (although the sync may send and receive more data since it's probably a postback). But you can intercept both of those requests, manipulate them, and resend them and cause havoc on your server.
Fiddler's a great tool, by the way. It's an eye-opener in terms of what kind of data and how much data you're sending to the server.