问题
Is it considered bad practice to combine synchronous and asynchronous socket calls on the same server? For example (modified from the msdn):
// Initalize everything up here
while (true) {
// Set the event to nonsignaled state.
allDone.Reset(); //allDone is a manual reset event
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();
// Handle the newly connected socket here, in my case have it
// start receiving data asynchronously
}
In this case, because you are waiting until each connection has been made before listening to the next connection, it seems like this is pretty much a blocking call. Given it should be a little bit faster because the initial handling of the client will be done it a different thread, but that should in theory be a relatively small overhead.
Given this, would it be considered bad practice to do something like:
while (true) {
// Start listening for new socket connections
Socket client = listener.Accept(); // Blocking call
// Handle the newly connected socket here, in my case have it
// start receiving data asynchronously
}
as in my mind, this code is much simpler then the code above, and if I'm correct should have a relatively close performance to the above code as well.
回答1:
Looking at your two examples, I see very little difference (if any at all) in what's occurring. I'd venture that your second form (going straight for the synchronous call) is better because it's far less complicated and is behaviourally identical. If you could look at the source for Accept, at some point (probably in the OS) it will be doing much the same as your more verbose code.
However...
A very quick mod to your old code eliminates all blocking and lets everything occur asynchronously:
void Accept()
{
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(AcceptCallback, listener);
}
public static void AcceptCallback(IAsyncResult ar) {
var listener = (Socket)ar.AsyncState;
//Always call End async method or there will be a memory leak. (HRM)
listener.EndAccept(ar);
Accept();
//bla
}
mmmm... much better.
来源:https://stackoverflow.com/questions/4000644/mixing-synchronous-and-asynchronous-socket-calls