Are calls synchronous in WCF? - c#

I'm writing an App using WCF where clients subscribe to a server and then updates get pushed back to the clients.
The subscribers subscribe to the server using a DuplexPipeChannel calling a Subscribe() method on the server.
The server maintains a List<> of subscribers and when there is data to push out to the subscribers it calls a PushData() method.
My intention is to iterate through the list of subscribers calling the push method on each of them in turn.
What I want to know is: Is calling the push method on my Subscriber blocking? Will a failure of connectivity or delay in connecting to one of the subscribers cause the rest of the push calls to be delayed (or worse fail)?
I'm sorry if this is an obvious question, but I've been mostly a .Net 2.0 person up until now so I know very little about WCF.
My WCF code is loosly based on this tutorial.
Another Question
Assuming it is synchronous, am I better off spawning a new thread to deal with the client side requests or would I be better off spawning a new thread for each "push serverside?"

WCF calls are synchronous by default, although they can be configured to be asynchronous. See Jarrett's answer below. Take a look here. Every message you send will receive a result back, whether you actually are expecting data or not.
The call will block depending on what your server does. If PushData on the server actually iterates through the subscriber list and sends a message to each, it will. If PushData only inserts the data and another thread handles sending the data to the subscribers, it will only block while your server inserts the data and returns.
Hope this helps.
Edit: Regarding spawning threads client-side vs server-side. Server-side. If a client calls takes a while, that's while, but if it takes a long time because the server is actually sending out calls to other clients in the same call, then something is wrong. I would actually not really spawn a new thread each time. Just create a producer/consumer pattern on your server side so that whenever a data item is queued, the consumer picks it up. Hell, you can even have multiple consumers.

If you right-click on the Service Reference, you have the option to create Async calls. (There's a checkbox on the setup dialog.) I usually create Async methods and then listen for a result. While it is a bit more work, I can write a much more responsive application using async service operations.

Related

Socket ReceiveAsync, Timeouts and Questions

I need to reimplement a database connection driver for some legacy cobol database for one of my customers. The way the application is built, i cannot use async/await (just leave it like that, i know it is stupid).
The whole application is an ASP.NET API.
The old driver uses a c++ dll, that is included with inter-op methods. The idea behind the old system is: use one connection to the db for everything, have multiple threads send a packet and have one thread that receives the answers and delegates them to the right thread.
To keep the connection alive, one needs to send some sort of ping message to database and handle its pong message.
I reimplemented that as POC in c#, have one connection, open a background thread and use AutoResetEvents to notify the right threads that the answer is ready to be processed. I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server.
A reason for the rewrite is, that the one-connection-solution does not scale.
So, my idea is to use a socket pool and ReceiveAsync with SocketAsyncEventArgs on the sockets.
The solution works so far, but not really good. Here are some questions:
As ReceiveTimeout is not compatible with ReceiveAsync, is there a other way then a timer to send my ping-messages
when using ReceiveAsync, can i still use normal Send to send data, or do i have to use SendAsync?
when ReceiveAsync does not receive all required data, may i use Receive to read the rest of it, or is it better to use ReceiveAsync again for the missing data?
Maybe not relevant: I use Artillery to fire some performance tests on the new driver; from time to time they timeout after 30 seconds (thats the db-transaction timeout i set); when i try to debug that Artillery gets ESOCKETTIMEDOUT even though no breakpoint is hit - is this a known behaviour when debugging an IIS process under load?
use AutoResetEvents to notify the right threads that the answer is ready to be processed.
May I suggest a thread-safe queue? BlockingCollection<T> or BufferBlock<T>?
I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server.
This is weird. I assume the entire protocol is ping-pong based, or else using a receive timeout to send messages would not work.
my idea is to use a socket pool and ReceiveAsync with SocketAsyncEventArgs on the sockets
If you can't use async/await, I would advise switching to the Begin*/End* style of asynchronous API. Going straight from synchronous to SocketAsyncEventArgs is quite a leap; SocketAsyncEventArgs is the most difficult form of socket async programming.
is there a other way then a timer to send my ping-messages
I would recommend a timer; that's the normal solution for heartbeat messages. The desired semantics should be "we want to send data at least this often". So use a timer that you can reset when sending regular messages (not receiving messages).
when using ReceiveAsync, can i still use normal Send to send data, or do i have to use SendAsync?
You should be able to use synchronous for one stream and asynchronous for the other. I've never tried this, though; all systems I've worked on are fully asynchronous.
when ReceiveAsync does not receive all required data, may i use Receive to read the rest of it, or is it better to use ReceiveAsync again for the missing data?
This question doesn't make as much sense to me. If you're asynchronously reading, you shouldn't block the calling thread.
Also, I think this question is framed from the wrong perspective. It seems like the code wants to "receive the next message", but this is a problematic way to approach reading from a socket. Instead, I recommend that your code have a loop that endlessly reads from the socket and passes that data to another type that buffers it as necessary and pushes out messages as they finish.
is this a known behaviour when debugging an IIS process under load?
I would not expect so, but I don't have much IIS load testing experience.

How do asynchronous GET requests work?

I THINK I understand the basic principle of an asynchronous POST method from a high level view point. The big advantage is that the caller gets a quick response, even though the processing of the data from the POST might not be completed yet.
But I don't really understand how this applies to a GET method. The response needs to contain the data, so how can there BE a response before processing is completed? Why have an API with a GET request handler that utilizes asynchronous methods?
I don't think it matters for this general type of question, but I'm writing in C# using Web API.
On the network there is no such thing as an async HTTP call. It's just data flowing over TCP. The server can't tell whether the client is internally sync or async.
the caller gets a quick response
Indeed, the server can send the response line and headers early and data late. But that has nothing to do with async IO or an async .NET server implementation. It's just some bytes arriving early and some late.
So there is no difference between GET and POST here.
why ... utilize asynchronous methods?
They can have scalability benefits for the client and/or the server. There is no difference at the HTTP level.
So the app can do other things that don't need the data.
If you implement a GET as synchronous (and let's say you are on a bad network, where it takes 20 seconds to get it), you can't
Show progress
Allow the user to cancel
Let them initiate other GETs
Let them use other parts of the app
EDIT (see comments): The server wants to respond asynchronously for mostly the same reason (to give up the thread). Actually getting the data might be asynchronous and take some time -- you wouldn't want to block the thread for the whole time.
It doesn't make any sense if you're building a RESTful API, in which GET should return a resource (or a collection) and be idempotent (not make any changes).
But if you're not following those principles, a GET request could perform some work asynchronously. For example, GET /messages/3 could return the message to the client, but then asynchronously do other work like:
mark the message as read
send a push notification to the user's other clients indicating that the message is read
schedule a cronjob 30 days in the future to delete the message
etc.
None of these would be considered a RESTful API, but are still used from time to time.

Synchronous Vs Asynchronous related to web services

I was trying to find a good explanation for the difference between synchronous communication vs asynchronous communication for web services, all over the internet. but it seems that even the people who is willing to provide an answer to the problem is also confused with it. and one answer is the complete vice versa for another answer.
If anybody can provide a good explanation about the difference of above matter with a clear idea, it would be helpful for everybody who would face the same problem in the future.
Asynchronous service
Say you have a long running web service (say it reads a large file from the file system and does some processing).
If you set this up as a 'synchronous' web service (using the WCF definition of that), then the calling client will have to wait until the processing completes, and typically this will block on one of the asp.net worker threads while processing completes. For a service with high traffic, this can become problematic.
If you set this up as an asynchronous web service, then what you are saying is that your code is going to delegate some of the long running processing to another thread, or use a non-blocking mechanism, and that this will return at some point in the future (if you are using c# 5.0, then you might want to look at examples of the async and await keywords).
For the example, reading a large file could be done using one of the async ReadFile methods.
This will not block one of the asp.net worker threads, allowing potentially greater throughput.
(There is often some confusion when people refer to making multiple simultaneous calls to the same service (often via AJAX from a web page) - while the calls from the page will typically be made using an asynchronous mechanism in javascript, this is not quite the same as what is described above - I like to keep a distinction between multiple parallel calls and asynchronous calls in my head)
Asynchronous calls
It's also worth noting that you can make an asynchronous call to a service even if that service is not set up to be 'asynchronous'. This is how AJAX calls in javascript will work, e.g.
var jqxhr = $.ajax( "AnyService.svc" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });
alert("Called");
For this example, you would expect to see 'Called' displayed before 'Success', as this will not wait for the service to return prior to proceeding. The service you are calling does not have to be 'asynchronous'.
Edit
As pointed out in the comments, you can also have a client that calls an 'asynchronous' service in a synchronous manner (i.e. the service will not block worker threads for further requests, but the client will block at that side).
First lets clear your doubt about Synchronous and asynchronous
Synchronous communication is direct communication where the communicators are time synchronized. This means that all parties involved in the communication are present at the same time. This includes, but is not limited to, a telephone conversation (not texting), a company board meeting, a chat room event and instant messaging.
Asynchronous communication does not require that all parties involved in the communication to be present at the same time. Some examples are e-mail messages, discussion boards, blogging, and text messaging over cell phones. In distance (specifically online) education asynchronous communication is the major (sometimes the only) method of communication. Usually, we use different discussion boards in each class with each having its own purpose.
e.g.
synchronous
When I call you on the phone, I dial your number and WAIT until you pick up. Then you say something, and in the very same moment I listen to you. When you finished, I send you data (talk to you) and in the same moment you receive them (listen to me). At the end of our communication one of us says "END OF TRANSMISSION" (Good Bye), the other says "Acknoledged" (Good Bye) and then both ring off.
asynchronous
I write you a letter. I put it to the postoffice, and it will be sent to you. I the meantime I do NOT WAIT. I do many different other things. Then you receive the letter. You read it while I still do many different other things. Then you write me an answer and send it to me. In all those things I am not involved. At the next day I get a (synchronous) message (a signal) from the system (postman). It (he) says: "Here is a message for you". Alternatively I could poll my inbox every five minutes to check if a new letter is there. Then I pause my other work, receive your letter and read your answer. Then I do something according to this answer. But this are things you will not notice, because you are not involved in what I do with your asynchronous answer.
courtesy: How does Synchronous and Asynchronous communication work exactly
well you are not very specific with your problem, but this might help:
at the most basic level synchronous communication is when the communication with the server takes place at the same time that other requests for other assets are sent. for example an ajax call will block other assets from downloading if it is synchronous.
asynchronous communication is when the communication is independant of other assets in the web service/page. this sort of communication is used more often.
Synchronous - You are making a call to a friend, He picked up the call and responded to you.
Asynchronous - You have sent a text to your friend on his mobile, But your friend might reply instantly or may reply 10mins after or may be after 2 days. This case you don't expect a instant answer from your friend.

Implementing a TCP/IP JSONRPC connection in C# - Need design Advice

I'm working on implementing a JSON RPC connection over TCP/IP and I have one fundamental issue. Currently I'm using a synchronous approach, which works well.
I can send
{"id":1,"jsonrpc":"2.0","method":"Input.Home"}
and receive
{"id":1,"jsonrpc":"2.0","result":true}
This works with no problems. The issue arises when I receive notifications. These can arrive unpredictably and at any time. I am interacting with the XBMC JSON RPC API. If a notification has been sent by XBMC, I receive multiple JSON requests at once. E.g.
{"jsonrpc":"2.0","method":"GUI.OnScreensaverActivated","params":{"data":null,"sender":"xbmc"}}{"jsonrpc":"2.0","method":"GUI.OnScreensaverDeactivated","params":{"data":null,"sender":"xbmc"}}
This causes a crash in JSON.NET, and understandably so. My first instinct is I need to asynchronously receive these notifications so that I don't have to wait until the next method is called to receive them. However this complicates the simple example I showed above because I can no longer utilize the synchronous calls. i.e.
SendJson(json);
result = ReceiveJson();
Is there a clean way to implement this without over complicating it? Any/All advice is appreciated.
Here is where all the reading is. Its all worth it if you want to get into it.
http://msdn.microsoft.com/en-us/library/ms228969.aspx
For a summary though..
Basically what needs to happen is you need to create an object that implements IAsyncResult. This will store state about your async operation, and a callback for when it is complete.
Create a method that can take your IAsyncResult object as input, and before the method returns, it should call .SetCompleted() on your IAsyncResult object. Its inside this method that you do the work you normally do.
Then you will create an instance of your IAsyncResult object (set its data, and callback), then call Task.Factory.StartNew([YourNewMethod],[YourInstanceOf IAsyncResult]).
That is the core of what needs to happen. Just make sure to set your callback and handle exceptions.
If you want a working example of how I and using an async http handler to do json-rpc, take a look at http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#74311 also where Process is being called and the async object is being setup http://jsonrpc2.codeplex.com/SourceControl/changeset/view/13061#61720
Hope that helps.

What is the recommended way to pass data back and forth between two threads using C#

I am trying to make an app that will pass data between two servers Connection1 and Conenction2 using sockets.What i would like to do is receive data from Connection1 and pass it to Connection2 and vice-versa.Connection1 and Conenction2 are on different threads. What is the best way to call methods on different threads in order to pass data back and forth between them.Both threads will use the same message object type to communicate in both directions between them.
Thanks
You should use immutable data transfer objects.
As long as a simple object is deeply immutable (meaning that neither it nor any of it's properties can change), there is nothing wrong with using it on multiple threads.
To pass the instances between threads, you might want to use a pseudo-mutable thread-safe stack. (This depends on your design)
If .NET 4 is an option, I'd strongly recommend having a look at the ConcurrentQueue<T> and possibly even wrapping it with a BlockingCollection<T> if that suits your needs.
That depends on what those threads are doing. While passing data between threads is relatively straight forward, waking the threads to process the data can be more tricky. When you design communication with a thread per/connection paradigm, your thread is almost all the time stuck in a Read method, like Socket.Receive. While in this state, other threads cannot actually wake this thread to have him send the data they want it sent. One solution is to have the Receive time out every second and check if it has data to transmit, but that just plain sucks.
Another idea is to have 2 threads per socket, one to Send one to Receive. But then all the advantages of having a thread per socket are gone: you are no longer able to have a simple state management of the 'session' in the thread code, you have a state shared between two threads and it's just a mess.
You can consider using async Receive instead: the socket thread posts a BeginReceive then waits on an event. The event is signaled by either the Receive completion or by the send queue having something 'dropped' in (or you can wait on multiple events, same thing basically). Now this would work, but at this moment you have a half-breed, part async part one-thread -per-socket. If you go down this path, I'd go the whole 9 yards: make the server fully async.
Going fully async would be the best solution. Instead of exchanging data between threads, completion routines operate on locked data. The Connection1 BeginReceive completes when it receives data, you parse the received data and analyze the content, then decide to send it on Connection2. So you invoke BeginSend on Connection2's socket, meaning the thread that received the data also send the data. This is much more efficient ans scales better than the thread-per-socket model, but the big disadvantage is that is just plain complicated if you're mot familiar with async and multithreaded programming.
See Asynchronous Server Socket Example and Asynchronous Client Socket Example for a primer.
What you are describing as asynchronous messaging. Microsoft has already written an app for this called MSMQ
I would use WCF on .NET 3.5 for this task, it will be more scalable. I'm using WCF for a lot of my works and its flawless. The good thing about it is you can share your data across any platform.
http://msdn.microsoft.com/en-us/netframework/aa663324.aspx

Categories

Resources