My connection handler is below (this is more for personal experimentation than production code)
If I don't add a Thread.Sleep anywhere in the while loop, it starts sucking down CPU.. Conversely, if I do Sleep to alleviate the endless while-spam, I miss the disconnection.. The CPU goes up in direct proportion to the number of clients/threads running, so it's not the listener itself that's causing the high usage, it's the actual client thread posted below.. Anyone have any ideas on how to solve this?
(I'm avoiding await-based solutions as I'm not familiar enough with async/await and the threaded method is working fine for this rather small project)
I only briefly searched around SO looking for a solution and didn't notice any that were this specific problem or that provided a solution other than directing folks to async/await articles, so sorry if I did miss an applicable answer.
private void HandleConnection(CancellationToken ct) {
int recv = 0;
byte[] buf = new byte[4096];
Trace.WriteLine($"{_name} Connected");
if (_ns.CanWrite && _client.Connected) {
_ns.Write(Encoding.BigEndianUnicode.GetBytes("■WEL"), 0, Encoding.BigEndianUnicode.GetBytes("■WEL").Length);
try {
while (_client.Connected && !ct.IsCancellationRequested) {
while (!_ns.DataAvailable) { //first attempted solution
Thread.Sleep(100); // miss discon if i sleep here
}
if (ct.IsCancellationRequested) {
Trace.WriteLine($"{(string)this} thread aborting");
break;
}
buf = new byte[4096];
if (_client.Connected && _ns.DataAvailable) {
recv = _ns.Read(buf, 0, buf.Length);
} else {
recv = 0;
}
if (recv > 0) {
string r = Encoding.BigEndianUnicode.GetString(buf);
r = r.TrimEnd('');
if (String.IsNullOrEmpty(r) || String.IsNullOrWhiteSpace(r))
r = null; //need the !not version
else
if (ParseMsg(r))
break;
}
//Thread.Sleep(100); // also miss discon here too
}
} catch (IOException ioe) { }
Trace.WriteLine($"{_name} Disconnected");
if (OnDisconnected != null)
OnDisconnected(this);
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…