I am developing a WCF RESTful web service which only accept HTTP. I have few questions about changing to async pattern.
Almost all examples that demonstrates how to use TPL to implement async WCF operation contract use client based on WCF client proxy, in my case client could be a browser that only support HTTP verbs, so it seems changing my WCF service to async pattern is not so meaningful. Can I say, if a service is RESTful and each request doesn't take very long to process, I will not benefit a lot from changing service synchronized to async?
If my service operation contracts either is a OneWay service or return nothing to client, operation contract should be defined as async Task DoSthAsync() or void DoSth()? What is the difference here? In other words, should I await/return the Task.Run or not.
My service accepts big chunk of data send from client using HTTP POST, suppose the processing would take a while, so changing to async pattern could improve service concurrency and throughput, how to make sure that the pass-in stream object is not disposed by WCF in Task.Run(() => {})delegate?
1.Almost all examples that demonstrates how to use TPL to implement async WCF operation contract use client based on WCF client proxy, in my case client could be a browser that only support HTTP verbs, so it seems changing my WCF service to async pattern is not so meaningful. Can I say, if a service is RESTful and each request doesn't take very long to process, I will not benefit a lot from changing service synchronized to async?
Question 1 is totally out since you said you want to use TPL on the WCF server side and not client side.
#CodingYoshi I have no assumption on clients. I totally focus on server side here.
.
2.If my service operation contracts either is a OneWay service or return nothing to client, operation contract should be defined as async Task DoSthAsync() or void DoSth()? What is the difference here? In other words, should I await/return the Task.Run or not.
You do not specify in your service contract whether a service is async or not. That is internal to your service. Whether your service is doing things asynchronously or not, the client can still call your service synchronously or asynchronously. For example, if your service writes stuff to a file and the writing takes 5 minutes and you have implemented to do this synchronously, the client can still call your service asynchronously (or synchronously). If you have implemented this asynchronously, then the threadpool thread which handled the call will be free to handle other calls. In other words, the changes will only be effecting the server side.
Also keep in mind, if you are doing something which is truly async then doing it asynchronously will be beneficial. If you are doing a CPU intensive operation, then doing it asynchronously will actually hurt performance. Why? Because when a request comes to ASP.NET (WCF, MVC, Web Forms or whatever) the most efficient way to handle the request is to do it using one thread-pool thread. If you are doing a CPU intensive operation then whether that thread does it, or you start a Task and another thread takes over, will be no different. However, you will pay the price for switching contexts.
3.My service accepts big chunk of data send from client using HTTP POST, suppose the processing would take a while, so changing to async pattern could improve service concurrency and throughput, how to make sure that the pass-in stream object is not disposed by WCF in Task.Run(() => {})delegate?
When a request arrives at the WCF gate, whether you handle it asynchronously or synchronously, the response will not be sent unless and until the whole operation is completed. So why would the passed in stream be disposed?
I think you are not clear on the whole async concept. Whether your service is async or not, the client will still need to make sure the calls are not blocking. For example, if the clients calls an operation, they can either:
Wait until they receive a response and do nothing else or
Call the service, do other things and once the response returns, they handle the response.
Related
I have a problem statement where a product is making an outbound call to a self-hosted service in a synchronous way, and is expecting the response in synchronous manner.
In order to provide the response, my self hosted service needs to do a lot of async operations and goes to on-prem. On-prem sends back the response to receiver service, and while sending the response back to self-hosted service, I am not able to identify the response belongs to which request.
I have read about semaphore, and was wondering if that could be used to solve this.
For example:
Main state of each thread in Semaphore
Let the self hosted service do the usual work, and wait for something
Once I have the response from on-prem and SNS sends an event, awake to do the further processing
High-level architecture
Kindly note: I can't change the flow or the architecture
We have a WCF + Rest service running on the host. I need to make a client call to the host that would initiate a long running task on the server (even up to 15 min), then check back once that process has finished to get the result. One solution is to have client checking the host every minute or so after the initial call - but that seems not very productive. Is there a way to expose some type of event through WCF so that client would be notified when the task completed on the server? What is the best approach for this type of scenario?
thanks
Kind of hard to answer without more application details.
But have a few alternatives (here are a few of them):
Use a message queue to initialize and get events when then task is
done (perhaps overkill)
If the client is a web client and you have the possibility ta have a web socket to the client you can notify the client that the task is done
Perhaps (not sure this is a good idea)
you can use duplex wcf contract (since you already use wcf), then the
service can invoke a method on the client interface when the task is
done
Or do a simple polling calls like you mention in your question.
Here are some more information regarding duplex contracts:
https://msdn.microsoft.com/en-us/library/ms731064%28v=vs.110%29.aspx
The following link http://msdn.microsoft.com/en-us/library/hh211418(v=vs.110).aspx explains the new asynchronous programming features with the 4.5 .Net framework, which for the most part is fairly straight forward reading.
However, I just want to make sure of something....
If I am using a SQLDataReader in a web service and I create a service reference on the client to use that web service by generating asynchronous methods in the proxy (via the service reference dialog options), I very well imagine I wouldn't need to use the methodologies mentioned in the link above.
Rather, I would use the async, Task, and await keywords on the client appropriately when calling that web service method
Since checking those options on the Web Service dialog, it will automatically create asynchronous method calls for the ADO.Net call.
So, if you have a method called GetCategories in the web service, it will automatically create an asynchronous call called GetCategoriesAsync in the web service which could be called from the client. Again, no need to place the asynchronous attributes on the web service method call; only for an ADO.Net call which is not using a web service or one which is using a web service, but does not have the asynchronous options checked.
Am I correct in my thinking?
It depends on what you want to make asynchronous.
Network communications are inherently asynchronous. When Visual Studio creates a client proxy for your web service, it creates both asynchronous and synchronous methods (where the synchronous methods just block waiting for a response). So, your web client can be asynchronous, and this is true regardless of how the server is implemented. In other words, a server can be synchronous or asynchronous, and a client can be synchronous or asynchronous, completely independent from each other.
On the client side, you should almost always use asynchronous methods on the proxy. The primary benefit on the client is responsiveness.
On the server side, you can get a scalability benefit by using an asynchronous implementation. However, if your backend is a single SQL server database, and every request hits that database, then there usually isn't a benefit from making your web service asynchronous. This is because (in that case) the scalability bottleneck is the SQL server, not the web server. OTOH, if your backend is a SQL server cluster or Azure SQL, then you can get a scalability benefit by using an asynchronous web service implementation.
The old-style common scenario was client <-> API <-> DB, and in that architecture there's no real need for asynchronous DB access. However, more and more architectures are looking like client <-> API <-> cloud storage / APIs, and that's when async really brings benefits to the API layer.
We connect with multiple (Around 15-20) third-party web services within our C# Web Application. We are attempting to find the best way use Multi-Threading or Async to call multiple web services (2-5) at the same time.
What would be the best way to do this?
Multi Threading
Async Calls
It needs the ability to:
Connect to Web Service A
Send the request,
Connect to Web Service B
Send the request
Connect to Web Service C
Send the request
Etc...
.. All while waiting for the response for WS A, B, C, etc...
I know I need to be using IAyncResult, but i've seen some examples and some use MultiThreading and some do not. What would the best way be?
You don't mention it in your question, but you've tagged the question with the WCF tag so I'm going to assume that you are trying to make these calls with the WCF client proxy model. If this is not the case, please explain what client technology you are using and I can revise my answer.
First, I highly recommend you read this documentation on MSDN: How to: Call WCF Service Operations Asynchronously
First, what you'll be doing is generating your WCF client proxy classes with SvcUtil.exe, but specifying an additional flag, /async (or simply /a), which will generate Asynchronous Programming Model (APM) method signatures. Once you've got those client proxies generated you can simply call them like you would any other APM method and supply a callback that will be invoked once the response is available.
Utilizing the APM based WCF signatures will make the outgoing and pending network I/O completely asynchronous which will free up your "main" thread to make the 15-20 calls you need to make concurrently. Also, while the network calls are outstanding, no CPU thread will be wasted.
Now, if you're on .NET 3.5 you'll have to use some kind of synchronization primitive to wait on and signal once each of the callbacks has completed. Unfortunately there's no CountdownEvent class in 3.5 either, but you can just use Interlocked::Decrement to do the countdown and then signal a ManualResetEventSlim when it reaches 0 (or find a third party library that provides this). If you're on .NET 4.0, you can instead combine the APM model with the Task-based Asynchronous Programming (TAP) model leveraging TaskFactory::FromAsync and shove all the Tasks into a List<Task> and then use Task::WaitAll to wait for them all to complete before continuing fwd. Finally if you're on .NET 4.5 you could even combine that gracefully with C#'s async keyword and Task::WhenAll instead and save yourself a lot of manual TPL continuation logic.
I have a c# WCF web service which is a server and I do have 2 clients one is java client and another is c++ client. I want both the clients to run at the same time. The scenario I have and am unable to figure it out is:
My java client will be making a call to the WCF web service and the processing time might take around 10 mins, meanwhile I want my c++ client to make a call to the web service and the get the response back. But right now I am just able to make a call to web service using c++ client when the java client request is being processed. I am not getting the response back for c++ client request until java client request is completed.
Can any one please suggest me how to make this work parallel. Thanks in advance.
Any "normal" WCF service can most definitely handle more than one client request at any given time.
It all depends on your settings for InstanceContextMode:
PerSession means, each session gets a copy of the service class to handle a number of requests (from that same client)
PerCall means, each request gets a fresh copy of the service class to handle the request (and it's disposed again after handling the call)
Single means, you have a singleton - just one copy of your service class.
If you have a singleton - you need to ask yourself: why? By default, PerCall is the recommended setting, and that should easily support quite a few requests at once.
See Understanding Instance Context Mode for a more thorough explanation.
Use
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]
attribute over your service class. More on this for example here:
http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and
This is peripheral to your question but have you considered asynchronous callbacks from the method that takes 10+ minutes to return, and then having the process run in a separate thread? It's not really good practice to have a service call waiting 10 minutes synchronously, and might solve your problem, although the service should allow for multiple callers at once anyway (our WCF service takes thousands of simultaneous requests).
When you call a WCF you have a choice in either calling it synchronously or asynchronously. A synchronous call waits for the response to send back to the caller in the same operation. In the caller it would look like "myresult = svc.DoSomething()". With an asynchronous call, the caller gives the service a function to call when it completes but does not wait for the response. The caller doesn't block while waiting for the response and goes about its business.
Your callback will take DoSomethingCompletedEventArgs:
void myCallback(object sender, DoSomethingCompletedEventArgs e)
{
var myResult = e.Result;
//then use the result however you would have before.
}
You register the callback function like an event handler:
svc.DoSomethingCompleted+=myCallback;
then
svc.DoSomethingAsync(). Note there is no returned value in that statement; The service would execute myCallBack when it completes and pass the result. (All WCF calls from Silverlight have to be asynchronous but for other clients this restriction isn't there).
Here's a codeproject article that demonstrates a slightly different way in detail.
http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr
This keeps the client from blocking during the 10+ minute process but doesn't really change the way the service itself functions.
Now the second part of what I was mentioning was firing off the 10+ minute process in a separate thread from inside the service. The service methods themselves should be very thin and just be calling functionality in other libraries. Functions that are going to take a long time should ideally be called in their own threads (say a backgroundworker, for which you register on the service side a callback when it completes) and have some sort of persistent system to keep track of their progress and any results that need to go back to the client. If it were me I would register the request for the process in a db and then update that db with its completion. The client would then periodically initiate a simple poll to see if the process was completed and get any results. You might be able to set up duplex binding to get notified when the process completes automatically but to be honest it's been a few years since I've done any duplex binding so I don't remember exactly how it works.
These topics are really too big for me to go into depth here. I would suggest researching multithreaded operations with the BackgroundWorker.