c# - Does async/await affects tcp server performance? -
i creating tcp server in c# 5.0 , using await keyword when calling tcplistener.accepttcpclientasync
, networkstream.readasync
however when check cpu usage of server process explorer have following results:
tcp sync version: 10% cpu usage
tcp async version: 30% cpu usage half of usage kernel usage.
moreover, measured how many time received data adding counter inside while of network stream, , async version loops 120,000 times while sync version loops 2,500,000 times.
in term of message received/second async version 15% slower sync version when receiving messages 3 different clients.
why async version use lot more cpu sync version?
is because of async/await keyword ?
is normal async tcp server slower sync counterpart?
edit: here example of async tcp server code
public class asynctcplistener : itcplistener { private readonly serverendpoint _serverendpoint; // custom class store ipaddress , port public bool isrunning { get; private set; } private readonly list<asynctcpclientconnection> _tcpclientconnections = new list<asynctcpclientconnection>(); private tcplistener _tcplistener; public asynctcpmetriclistener() { _serverendpoint = getserverendpoint(); } public async void start() { isrunning = true; runtcplistener(); } private void messagearrived(byte[] buffer) { // deserialize } private void runtcplistener(){ _tcplistener = null; try { _tcplistener = new tcplistener(_serverendpoint.ipaddress, _serverendpoint.port); _tcplistener.start(); while (true) { var tcpclient = await _tcplistener.accepttcpclientasync().configureawait(false); var asynctcpclientconnection = new asynctcpclientconnection(tcpclient, messagearrived); _tcpclientconnections.add(asynctcpclientconnection); } } { if (_tcplistener != null) _tcplistener.stop(); isrunning = false; } } public void stop() { isrunning = false; _tcplistener.stop(); _tcpclientconnections.foreach(c => c.close()); } }
for each new client create new asynctcpconnection
public class asynctcpclientconnection { private readonly action<byte[]> _messagearrived; private readonly tcpclient _tcpclient; public asynctcpclientconnection(tcpclient tcpclient, action<byte[]> messagearrived) { _messagearrived = messagearrived; _tcpclient = tcpclient; receivedatafromclientasync(_tcpclient); } private async void receivedatafromclientasync(tcpclient tcpclient) { var readbuffer = new byte[2048]; // packetprotocol class comes http://blog.stephencleary.com/2009/04/sample-code-length-prefix-message.html var packetprotocol = new packetprotocol(2048); packetprotocol.messagearrived += _messagearrived; try { using (tcpclient) using (var networkstream = tcpclient.getstream()) { int readsize; while ((readsize = await networkstream.readasync(readbuffer, 0, readbuffer.length).configureawait(false)) != 0) { packetprotocol.datareceived(readbuffer, readsize); } } } catch (exception ex) { // log } } public void close() { _tcpclient.close(); } }
edit2: synchronous server
public class tcplistener : itcplistener { private readonly observerendpoint _serverendpoint; private readonly list<tcpclientconnection> _tcpclientconnections = new list<tcpclientconnection>(); private thread _listeningthread; private tcplistener _tcplistener; public bool isrunning { get; private set; } public tcpmetriclistener() { _serverendpoint = getserverendpoint(); } public void start() { isrunning = true; _listeningthread = backgroundthread.start(runtcplistener); } public void stop() { isrunning = false; _tcplistener.stop(); _listeningthread.join(); _tcpclientconnections.foreach(c => c.close()); } private void messagearrived(byte[] buffer) { // deserialize } private void runtcplistener() { _tcplistener = null; try { _tcplistener = new tcplistener(_serverendpoint.ipaddress, _serverendpoint.port); _tcplistener.start(); while (true) { var tcpclient = _tcplistener.accepttcpclient(); _tcpclientconnections.add(new tcpclientconnection(tcpclient, messagearrived)); } } { if (_tcplistener != null) _tcplistener.stop(); isrunning = false; } } }
and connection
public class tcpclientconnection { private readonly action<byte[]> _messagearrived; private readonly tcpclient _tcpclient; private readonly task _task; public tcpclientconnection(tcpclient tcpclient, action<byte[]> messagearrived) { _messagearrived = messagearrived; _tcpclient = tcpclient; _task = task.factory.startnew(() => receivedatafromclient(_tcpclient), taskcreationoptions.longrunning); } private void receivedatafromclient(tcpclient tcpclient) { var readbuffer = new byte[2048]; var packetprotocol = new packetprotocol(2048); packetprotocol.messagearrived += _messagearrived; using (tcpclient) using (var networkstream = tcpclient.getstream()) { int readsize; while ((readsize = networkstream.read(readbuffer, 0, readbuffer.length)) != 0) { packetprotocol.datareceived(readbuffer, readsize); } } } public void close() { _tcpclient.close(); _task.wait(); } }
i have issues async
, these findings: https://stackoverflow.com/a/22222578/307976
also, have asynchronous tcp server/client using async
example here scales well.
Comments
Post a Comment