C# can Socket.SendAsync be called while there is an existing send operation

Started by
4 comments, last by Core2Duo 14 years, 1 month ago
I'm writing Asynchronous server written C# 3.5. I'm trying to find out what happens when you call mySocket.SendAsync(mySocketAsyncEventArgs) using a socket and SocketAsyncEventArgs that's still sending the previous message. MSDN mentions it can be called from multiple threads, implying its thread safe and thus it queues up the messages to be sent, but it just doesn't feel right to make that assumption. If it doesn't, would having one server thread for receiving messages and posting them off to the worker threads, and another server thread for sending messages be the way to go ? Are there any agreed upon best practices for this ? Edit: extra info. I'm writing a game server, not a request/response (HTTP, etc) type server. [Edited by - MrMark on March 13, 2010 10:19:19 PM]
Advertisement
Normally you receive data and process it and put the data in a queue if it needs to be processed in the server loop. Sending normally happens at the end of the game loop. Calling SendAsync multiple times in different threads is possible, but it's better to combine the data yourself and send it out at regular intervals in the server loop. I'm not actually sure other than the callback the difference between SendAsync and BeginSend. The documentation is kind of awkward for their sockets.

ServerLoop as X ms
{
-Process state changing messages
-Update game
-Send packets out to players regulating the packets/second per user in case some users require throttled packets
}
The "Async" in SendAsync is for the API level, not the network level. Data is still ordered as you'd expect.

All data contained in a first call to SendAsync will be sent before the next call to SendAsync. However, if you call SendAsync twice in the same thread, and once from another thread, there is no guarantee of the ordering between those individual SendAsync calls.

Personally, I prefer the BeginSend/EndSend method of sending, but to each his or her own I guess :-)
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
The "Async" in SendAsync is for the API level, not the network level. Data is still ordered as you'd expect.

All data contained in a first call to SendAsync will be sent before the next call to SendAsync. However, if you call SendAsync twice in the same thread, and once from another thread, there is no guarantee of the ordering between those individual SendAsync calls.

Personally, I prefer the BeginSend/EndSend method of sending, but to each his or her own I guess :-)


By ordering you mean:
Sending 3 messages: AAA,BBB,CCC
coming out as CCCAAABBB
or
coming out as AABABCCCB

The first i can live with, the second is a nightmare !


btw whats the advantages of BeginSend/EndSend ?
If thread A sends AAA followed by aaa, and thread B sends BBB, then the following are the three possible orderings:

AAAaaaBBB, AAABBBaaa, BBBAAAaaa.

I like BeginSend/EndSend because they use the same async handler completion mechanism like any other async I/O in the .NET framework. I don't know if SendAsync maps straight to I/O completion ports (it may very well) and thread pools (I think the completion event callback might be marshaled to the main thread?), but I know BeginSend/EndSend maps directly to I/O completion ports and the thread pool, so it's about as efficient as you can make it. What you pay for that is the fact that the async handler (where you call EndSend) will be called from some thread that you don't have control over.

enum Bool { True, False, FileNotFound };

BeginSend : Created an IAsyncResult object for each operation where the object cannot be reuse and has a price to pay through object allocation and garbage collection.

SendASync : SendAsync reduces some overhead from asynchronous operation, it uses
SocketAsyncEventArgs which you created from within the application and it is reusable.

This topic is closed to new replies.

Advertisement