As stated in the first section of this article (.chm file - see note below)
One-way calls do not equate to asynchronous calls. When one-way calls
reach the service, they may not be dispatched all at once and may be
queued up on the service side to be dispatched one at a time... If the
number of queued messages has exceeded the queue's capacity, then the
client will block, even when issuing a one-way call.
If a one-way call is invoked, when does it return control to the caller? The introduction of the same article states that one-way calls are used for fire-and-forget operations, thereby simulating a kind of asynchronous call.
If a sessionful WCF service has a Login() one-way method which starts the session, when does this method return control to the caller? Does it return before the method is actually executed on the service? If so, how can I be sure that the method was performed on service?
If I wanted the service to return to the client the possible errors that occur during the login procedure, would be an asynchronous call the only way to achieve a fire-and-forget behaviour?
Note: The quote above is taken from an article called WCF Essentials - What You Need To Know About One-Way Calls, Callbacks, And Events by Juval Lowy, and can be found in the October 2006 issue of MSDN magazine. The link above is to a help file (.chm) format on MSDN. If you can't get the linked CHM file to work (I couldn't) you can open it with 7zip.
If a sessionful WCF service has a Login one-way method which starts
the session, when does this method return control to the caller?
For OneWay calls: The caller will continue to execute as soon as the service call is dispatched or queued. Basically as soon as the service successfully receives the call.
how can I be sure that the method was performed on service?
If the client does not get an exception, the service call was (or will be) performed. When the service call actual runs or whether it succeeded or threw an exception is unknown to the client.
If I wanted the service to return to the client the possible errors
that occur during the login procedure, would be an asynchronous call
the only way to achieve a fire-and-forget behaviour?
This does not make sense. Fire-and-forget by definition means forget the result. It does not return any values or errors to the client. However an asynchronous call is not fire-and-forget and would return errors.
Related
I intend to call async version for fire & forget scenarios e.g. 1. log writing in Azure Table Storage 2. Pushing a message to service bus.
I do not intend to block or await the external api call. However Web API throws following error:
Web Api + HttpClient: An asynchronous module or handler completed while an asynchronous operation was still pending
Seems the IIS request thread has to remain active. Even though we're not block api call.
Is there any way we could let the external API continue its operation, using Async/Await?
Is Async Web API good for any practical purpose?
Yes; async web APIs allow your web server to make maximum use of its resources. That is, it helps your web server scale further and faster.
Is there any way we could let the external API continue its operation, using Async/Await?
That's not what async/await is for. You're looking for "fire and forget", which is highly dangerous on ASP.NET, but it is possible.
I have a WCF service in which I have long running methods like get and process some kind of data and then return it to client. I have tried to use contracts similar to following
Task<string> ServiceMethod(string message);
The problem is if I want to return the same data to multiple clients from the service then how can I do it (How do I get and store information about clients who are requesting data).
Also if I need to call a background worker from the above method then how do I process in the runworker_completed and return the result to the above.
Additional info
The returning of same data to multiple clients is only in case the clients request the same data but since it takes time to get and process it so whenever it is available I want to return to all the clients who have requested it.
if I understand your question correctly, you want the service to callback clients when it finishes a long running process that generates data. As you have to take care of multiple clients, I would recommend that you use Duplex WCF. A duplex service contract provides for calling back a method on invoking client. The following code project link is good example for Duplex and has a lot more details
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
Note that you should have your own logic for maintaining the list of callback channels
I have stored a cache of Task in the service with the keys requested. Whenever the task for that key is completed I send back tasks to all the clients which had requested the same key.
Also for already existing functions with event based completion I have used TaskCompletionSource and stored it in the cache and again using it to send async response.
I'm writing a webservice that drops off a long-running bulk insert command to a sql db through a stored proc. I don't want the webservice hung up while waiting for a response from the db, so I'd like to just return an http response that lets the client know the request has been sent to the db after I start the task. But as soon as I return the response, the task will lose context and get trashed, right? How should I keep this alive?
In general, it's not a good idea to spin off something to do work from IIS. What happens if the AppPool restarts? What happens if there is an exception?
Instead, I would recommend writing a Windows Service and have it responsible for the work.
Based on your comments, I would see if you can ask for the following requirements (theoretically):
All external calls are done through the web service. The web service uses a separate assembly for the actual data access.
A separate windows service is used for long running processes, which would also use the same data access assembly the web service uses.
That is really the best way to go (but not necessarily doable based on requirements).
I think it's more of a architecture question than just about maintaining the 'context'. And talking about architecture, I think WCF webservices would help in your scenario.
What you would need is a service with callback contract. Where the service takes a request, returns an ack, stores the client context (for callback), and triggers off a long running database task in background. When the task completes, it reads client context and calls the callback handler with the result.
This article at MSDN suggests how to do a callback contract in webservice.
Hope this helps!
I am using netTcpBinding and from what I have read, percall instance context is the recommended way to use wcf. However does this mean that I will not be able to use asynchronous duplex callbacks? Because the service objects are destroyed between method calls so there is no way to perform an async callback on the client? Is this correct?
It seems that if I want to use percall for scalibility, I will be stuck with bad responiveness on client machine because as the callbacks cant be asynchronous. Or have I got it all wrong?
You mix up client instances and server instances. InstanceContextMode.PerCall means that every call from a client gets a new object serving that single request.
The callback channel(s) which you are talking about are communicating the other way round: They call methods in your client. Your client should stay alive and is a single instance from the servers point of view.
So all you need to persist on the server side after a method call is the clients operation context. Because thats the reference you need to send a message to your client by using the callback contract.
So as a result, you can use async callbacks with InstanceContextMode.PerCall, but you will have to provide some session state storage by yourself.
What do you mean exactly with asynchronous duplex callbacks?
You can use a normal duplex contract and then make calls to this in an asynchronous way so that the client doesn't block. Obviously the service object need to stay alive until it has called back to the caller.
I have a WCF service hosted in a Windows Service. I want a website to be able to call it asynchronously and then when the work is finished the WCF service will let the website know the result. I've looked at various ways of achieving this but I would like to get some more advice on which way would be best. I've looked into using callbacks but also read they can be unreliable. I've read about not doing it this way at all and just having another interface in my service for the website to query the status. I've looked at using MSMQ which at the moment looks like my preferred way forward but would like some more info on how to set this up or whether I shouldn't do it this way.
Does anyone have any advice please?
The nature of any communication on a network is unreliable. The statement:
I've looked into using callbacks but also read they can be unreliable
Assuming you mean WCF callbacks, they are as unreliable as the clients/servers themselves, they all use the same mechanism.
That said, you can store the client of your WCF service in the HttpApplicationState (if the call is application-wide) or HttpSessionState (if the call is local to a session).
When generating the proxy, make sure that you check the option (or specify on the contract) that you are using asynchronous calls.
Then, you would make the call, using a callback (delegate) to indicate when the async call completed.
When the call completes, you would then store the result in the session state.
If this is something that a client on the front end needs to be aware of, then the browser will have to poll your site, checking for the return result, redirecting to a page that can display the results when the result is populated.
Selecting a binding for your application depends on
Architecture of your application
Requirements
interoperability required or not.
response time of the application
availability of time to implement
Infrastructure you are using or want to use.
As your application is a web application and is built on a request/response model, you will not be able to use asyncronous or msmq style for this architecture(or is not adviceable), because there will not be any thread listining for a delayed async response or msmq call.
you can make use of one way Methods and direct calls to methods. in this case to reduce response time you have to device ways to optimize your service methods and the processing it is doing.