Asynchronous programming in ADO.Net - c#

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.

Related

Multiple Web Service Calls At Once

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.

Web Service and Events

I am unsure of whether this is possible and have conducted a handful of quick searches on the web and I don't think it is but here goes.
I have a web service (old school .asmx) which retrieves a list of items from a database. I want my client app to be notified if there are any items to be processed INSTEAD of the client app every so often making a request to the web service. Is this possible?
I know this is possible via WCF (duplex communication) however due to complications I can't use that approach.
Oops I just realised that I would also require the web service to poll itself or get something to call it asynchronously? Don't think this is a good solution...
Thanks in advance, Onam.
It is either polling (initiated by the client) or by maintaining a session like Exchange, Imap etc does. Classic .asmx communication is initiated by the client. Therefore it provides no events.
You can implement duplex yourself by developing a callback service hosted by your client. Your webservice can then invoke the callback client. However you must find a good solution to register and unregister the clients to the webservice.
Actually, I would not be a good idea to let the database invoke the items on each poll. You could cache the results in the logic layer referenced by the webservice. If you prefer the classic .asmx approach, you can create a bool method that checks whether new data is in the cache that is implemented by the logic. This would reduce the performance inpact, and then it won't be that bad to poll the server.

How to wait for result of asynchronous web service call in ASP.NET for best performance

In WebForms ASP.NET site (IIS, single app pool), I have call to lengthy web service method referenced in Visual Studio as Service Reference (.NET 4.0). Unfortunately I must wait for information from web service before I can serve page to user. Currently web service is called synchronously so server can’t reuse current thread to process other requests which has performance impact.
Of course I can generate asynchronous operations for service reference in Visual Studio and call BeginGetFoo instead of GetFoo, but still I must wait somehow for result from web service.
Here comes question. If I use AsyncWaitHandle.WaitOne (as below) will it be any better in whole application performance terms from synchronous call I use today?
IAsyncResult result = fooSoapClient.BeginGetFoo();
result.AsyncWaitHandle.WaitOne();
var foo = fooSoapClient.EndGetFoo(result);
And of course, if waiting can be done better I am open for suggestions.
You want to use an Asynchronous Page. See "Wicked Code: Scalable Apps with Asynchronous Programming in ASP.NET", also Asynchronous Pages in ASP.NET 2.0, which talks about web services and Asynchronous Tasks with RegisterAsyncTask.
You'd still be hogging the thread. A "safe" option would be to use ASP.NET MVC's async controllers: http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx
Ideally though, you shouldn't do long running things on a web request. Have a windows service or something process the long running task (that could get kicked off by a web request dropping something on a message queue or putting a task in a database) and poll from the client using ajax or something and then update the user when it's done.
If refactoring your code is not acceptable so you cannot follow #John Saunders's answer then the only thing you can do is increase the number of threads for the application. This will allow you to scale better but at some point it will have diminishing returns and you will start hurting the performance. What is more if you do not have users waiting on the request queue (i.e. more than 25 simultaneous users per core on your server) you don't need to do anything. Async programming in the web server helps only with scalability but not actual performance for a single user.

WCF comet and threads

I'm trying to use WCF to implement a comet style server push to an ajax web application.
In my WCF service, I've implemented a WaitForEvents method that calls Monitor.Wait to suspend the thread until new data arrives. At that point, the Monitor is pulsed, and the method returns the new data which closes the comet style request.
The request is made again when this happens.
Currently, this works fine but I noticed that WCF needs to create a new thread for each connected user. This is probably because the thread cannot be returned to the threadpool until data comes in, and so each connected user requires a new thread.
I want to make this implementation more efficient by having one thread service multiple connections. If I were to use a socket, this could be done by leaving the socket open and returning the thread to the thread pool first. When new data arrives, it will be delivered by another thread and we can write the new data directly to the socket and close it.
Does anybody know how this can be done via WCF?
I have been looking at "Push-Style Streaming" http://msdn.microsoft.com/en-us/library/bb472551.aspx and they mention that "WCF implements a "pull" model in which the application code (the service) returns an instance of Stream and relies on the lower-level infrastructure to pull data from this stream and write it out to the network." but I cant find any examples of this one the website.
Many thanks in advance!
Check out nComet
It's not using WCF, but I believe the author is working on a version that uses WCF. Contact him via codeplex and ask him :-)
"nComet is a .NET implementation of
the Comet (reverse-AJAX push)
architecture. This server-side
pipeline uses long-lived
client-initiated HTTP connections to
push messages to the client. Once the
client receives a response, it
immediately opens another HTTP
request, which the server holds until
a message is ready. This architecture
allows the server to push dynamic
html/xml/json/etc to the browser,
rather than the browser polling the
server.
This project is scoped to the .NET
server-side architecture, initially
providing a HttpListener (for a custom
host communicating with HTTP.SYS
directly) as well as a ASP.NET
implementation, where the ASP.NET
implementation can be hosted inside
IIS as well as an external process.
The library will simplify the
implementation of common message
patterns such as pushing the latest
data, as well as sync. Example code
and links to multiple client-side
javascript implementations will also
be provided."
You may also want to check out WebSync, a .NET comet implementation. Works just dandy with WCF.
(Disclaimer: I work for the company).

Implementing observer pattern using WCF

When I first posted this question I had strong coupling between my web service and application controller where the controller needed to open multiple threads to the service and as it received back data it had to do a lot of processing on the returned data and merge it into one dataset. I did not like the fact that the client had to so much processing and merge the returned data before it was ready to be used and wanted to move that layer to the service and let the service open the asynchronous threads to the suppliers and merge the results before returning them to the client.
One challenge I had was that I could not wait till all threads were complete and results were merged, I had to start receiving data as it was available. That called me to implement an observer pattern on the service so that it would notify my application when new set of results are merged and ready to be used and send them to the application.
I was looking for how to do this using either on ASMX webservices or WCF and so far I have found implementing it using WCF but this thread is always open for suggestions and improvements.
OK the solution to my problem came from WCF
In addition to classic request-reply operation of ASMX web services, WCF supports additional operation types like; one-way calls, duplex callbacks and streaming.
Not too hard to guess, duplex callback was what I was looking for.
Duplex callbacks simply allow the service to do call backs to the client. A callback contract is defined on the server and client is required to provide the callback endpoint on every call. Then it is up to the service to decide when and how many times to use the callback reference.
Only bidirectiona-capable bindings support callback operations. WCF offers the WSDualHttpBinding to support callbacks over HTTP (Callback support also exists by NetNamedPipeBinding and NetTcpBinding as TCP and IPC protocols support duplex communication)
One very important thing to note here is that duplex callbacks are nonstandard and pure Microsoft feature. This is not creating a problem on my current task at hand as both my web service and application are running on Microsoft ASP.NET
Programming WCF Services gave me a good jump start on WCF. Being over 700 pages it delves deep into all WCF consepts and has a dedicated chapter on the Callback and other type of operations.
Some other good resources I found on the net are;
Windows Communication Foundation (WCF) Screencasts
MSDN Webcast: Windows Communication Foundation Top to Bottom
Web Service Software Factory
The Service Factory for WCF
This sounds like a perfect use case for Windows Workflow Foundation. You can easily create a workflow to get information from each supplier, then merge the results when ready. It's much cleaner, and WF will do all the async stuff for you.
I'm not so sure that duplex is needed here... IMO, a standard async call with a callback should be more than sufficient to get notification of data delivery.
What is the biggest problem? If you are talking about async etc, then usually we are talking about the time taken to get the data to the client. Is this due to sheer data volume? or complexity generating the data at the server?
If it is the data volume, then I can think of a number of ways of significantly improving performance - although most of them involve using DTO objects (not DataSet/DataTable, which seemed to be implied in the question). For example, protobuf-net significantly reduces the data volume and processing required to transfer data.
One of the ways to achieve this is by invoking your WS asynchronously (http://www.stardeveloper.com/articles/display.html?article=2001121901&page=1, http://www.ondotnet.com/pub/a/dotnet/2005/08/01/async_webservices.html), and then updating the GUI in the callback.
However, you could have timeout problems if the querying of data takes too long. For example, if one of the supplier's web site is down or very slow, this could mean that the whole query could fail. Maybe it would be better if your business logic on the client side does the merging instead of WS doing it.
Not sure if this solution fits your particular task, but anyway:
Add paging parameters to your WS API (int pageNumber, int pageSize, out int totalPages)
Add a short-living TTL cache that associates request details (maybe a hash value) with output data
When your application asks for the first page, return it as soon as it's ready and put the whole bunch of collected/merged data to cache so when the next page is required you may use what is already prepared.
But note that you won't get the most up-to-date data, configure cache reloading interval cautiously.
The absolute best way to archive in your scenario and technology would be having some kind of token between your web app / library against your web service and your controller needs to have a thread to check if there are new results etc. However please note that you will require to get the complete data back from your WS as it's merge can result in removed items from the initial response.
Or I still think that handling threads would be better from controller with the use of WCF Webservices

Categories

Resources