CPU usage problem - c#

I have a network project, there is no timer in it. just a tcpclient that connect to a server and listen to receive any data from network.
TcpClient _TcpClient = new TcpClient(_IpAddress, _Port);
_ConnectThread = new Thread(new ThreadStart(ConnectToServer));
_ConnectThread.IsBackground = true;
_ConnectThread.Start();
private void ConnectToServer()
{
try
{
NetworkStream _NetworkStream = _TcpClient.GetStream();
byte[] _RecievedPack = new byte[1024 * 1000];
string _Message = string.Empty;
int _BytesRead;
int _Length;
while (_Flage)
{
_BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
_Length = BitConverter.ToInt32(_RecievedPack, 0);
_Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
if (_BytesRead != 0)
{
//call a function to manage the data
_NetworkStream.Flush();
}
}
}
catch (Exception exp)
{
// call a function to alarm that connection is false
}
}
But after a while the cpu usage of my application goes up(90%, 85%,...).
even if no data receive.
could anybody give me some tips about cpu usage. I'm totally blank. i don't know i should check which part of the project!

could anybody give me some tips about cpu usage
You should consider checking the loops in the application, like while loop, if you are spend so much time waiting for some condition to became true, then it will take much CPU time. for instance
while (true)
{}
or
while (_Flag)
{
//do something
}
If the code executed inside the while are synchronous, then the thread will be ending eating much of CPU cycles. to solve this problem you could executes the code inside the while in a different thread, so it will be asynchronous, and then use ManualResetEvent or AutoResetEvent to report back when operation executed, another thing to mentioned is to consider using System.Threading.Thread.Sleep method to till the thread to sleep and give the cpu time to execute other threads, example:
while(_Flag)
{
//do something
Thread.Sleep(100);//Blocks the current thread for 100 milliseconds
}

There are several issues with your code... the most important ones are IMHO:
Use async methods (BeginRead etc.), not blocking methods, and don't create your own thread. Thread are "expensive>" resources - and using blocking calls in threads is therefore a waste of resources. Using async calls lets the operating system call you back when an event (data received for instance) occured, so that no separate thread is needed (the callback runs with a pooled thread).
Be aware that Read may return just a few bytes, it doesn't have to fill the _ReceivedPackbuffer. Theoretically, it may just receive one or two bytes - not even enough for your call to ToInt32!

The CPU usage spikes, because you have a while loop, which does not do anything, if it does not receive anything from the network. Add Thread.Sleep() at the end of it, if not data was received, and your CPU usage will be normal.
And take the advice, that Lucero gave you.

I suspect that the other end of the connection is closed when the while loop is still running, in which case you'll repeatedly read zero bytes from the network stream (marking connection closed; see NetworkStream.Read on MSDN).
Since NetworkStream.Read will then return immediately (as per MSDN), you'll be stuck in a tight while loop that will consume a lot of processor time. Try adding a Thread.Sleep() or detecting a "zero read" within the loop. Ideally you should handle a read of zero bytes by terminating your end of the connection, too.
while (_Flage)
{
_BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
_Length = BitConverter.ToInt32(_RecievedPack, 0);
_Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
if (_BytesRead != 0)
{
//call a function to manage the data
_NetworkStream.Flush();
}
}

Have you attached a debugger and stepped through the code to see if it's behaving in the way you expect?
Alternatively, if you have a profiling tool available (such as ANTs) then this will help you see where time is being spent in your application.

Related

Thread executing remote connection won't abort

I'm designing a small program whose objective is to make sure one of our server is up and running. In some cases, the server won't answer and a script must be launched to restart the server.
First I'm starting a new thread responsible of fetching the information, which is then joined by the main thread for a certain time span. I then abort the thread to disconnect and finally join it to leave enough time to execute the catch and finally blocks.
In theory it should work great : if the time span is short enough, it indeed indicates that the server is down (because no connection could be made in the short allocated timespan). But in certain cases, when the server is really down, the program will just keep executing, as if the ThreadAbortException had no effect. Problem is, these downtimes are quite sporadic so I couldn't debug it myself to see what was not working properly.
Here's how it goes :
This here is the main thread, calling the worker thread. Very straightforward.
public void LaunchCommand()
{
Thread pingThread = new Thread(new ThreadStart(Ping));
pingThread.Start();
while (!pingThread.IsAlive);
pingThread.Join(new TimeSpan(0, 0, _maxTime));
pingThread.Abort(); // Time's up.
pingThread.Join(); // Make sure we complete everything before moving on
}
And here's the called thread :
private void Ping()
{
try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
serviceType = Type.GetTypeFromProgID(serviceProgID, _server, true);
service = Activator.CreateInstance(serviceType);
_xmlResult = ApxServiceType.InvokeMember("ExecuteXML", BindingFlags.InvokeMethod, null, service, new string[] { _dataset, Command, string.Empty }) as string;
stopwatch.Stop();
_latency = stopwatch.Elapsed;
// Trivial validations to make sure _status is true, such as _xmlResult.Contains(certainSubString); and such
_status = true; // Everything seems to work fine if we could make up to here.
}
catch (ThreadAbortException)
{
Console.WriteLine("Server timeout :(");
return;
}
catch (Exception e)
{
Console.WriteLine("Server exception: " + e.Message);
return;
}
finally
{
if (!_status)
{
_latency = new TimeSpan(0, 0, _maxTime);
}
}
}
Variables such as Commands, serviceProgID, etc. have been declared elsewhere and are known to work well. I guess my problem spans from the three lines following the stopwatch declaration/initialization. First, I must say I copy pasted these lines from a similar application, but basically it should only fetch a result from the given Command. Unfortunately, because I couldn't debug under the critical situation, I don't which line is problematic, but anyway, it seems the ThreadAbortException has no effect. Is it because code has been switched off to unmanaged?
I'm lost here so any idea would be welcomed! Thanks!
I actually don't see a need to use a separate thread for your scenario. You may check for server availability using synchronous operation. Does the function being used to check server availability offer timeout option? If yes then the timeout option should be enough. If the function returns before the timeout then it means server is online otherwise server is down.
If the function for checking server availability does not offer timeout option and may cause the thread to wait forever (or for a long time) then you may use a new thread. However if Thread.Join(Timeout) method returns true and _status variable is also true then you can be certain that the server is online. If Thread.Join(Timeout) returns false then it would mean that the server is down.
As a good practice, you should use Thread.ResetAbort in the catch block handling Abort exception. Otherwise runtime will rethrow the ThreadAbort exception once catch block finishes execution.

Is this bad programming?

Is this bad programming ?
DateTime dtExpire = DateTime.Now.AddSeconds(90);
while (client.Connected && DateTime.Now < dtExpire)
{
if (client.Available == 0) continue;
//or can also use: if (!networkStream.DataAvailable) continue;
dtExpire = DateTime.Now.AddSeconds(30);
//now do stuff with client via stream
}
The goal being to insure that the client does not take too mor time than the server is willing to wait to pocess incoming messages. Of course, this code is inside of a Try/Catch block, as well as a Using Stream block, so the server would gracefully handle dropped connections or any other socket exceptions.
Basically, I just want to know if there's a better way to handle this. Thanks.
Use the ReceiveTimeout property to specify how long to wait for an incoming message. When you use the Receive method (or its family of methods) and a timeout occurs, a SocketException will be thrown.
client.ReceiveTimeout = 90;
Your code will be more complex if you have to accomplish this asynchronously, but it doesn't look like you are. Receive by itself should do the job as it will block on the current thread.
This is called busy waiting.
You are essentially clogging the CPU even when there is no "real" work to be done (i.e. when you are just waiting on client.Available to become different from 0). Fortunately, your busy waiting has a timeout so at least it won't clog the CPU forever.
Whether you can do it more efficiently really only depends on what the client is and whether it implements a more efficient waiting strategy.
If it doesn't then you'll be stuck with some form of busy waiting, but not all is lost - if you can tolerate a slight delay in detecting the change in client.Available, then doing...
if (client.Available == 0) {
Thread.Sleep(max_delay_you_can_tolerate);
continue;
}
...would go a long way taking the pressure off the CPU.
--- EDIT ---
If client is in fact a Socket, take a look at Blocking and ReceiveTimeout properties.

thread get 100% CPU very fast

I am implementing a very basic thread in C#:
private Thread listenThread;
public void startParser()
{
this.listenThread = new Thread(new ThreadStart(checkingData));
this.listenThread.IsBackground = true;
this.listenThread.Start();
}
private void checkingData()
{
while (true)
{
}
}
Then I immediately get 100% CPU. I want to check if sensor data is read inside the while(true) loop. Why it is like this?
Thanks in advance.
while (true) is what killing your CPU.
You can add Thread.Sleep(X) to you while to give CPU some rest before checking again.
Also, seems like you actually need a Timer.
Look at one of the Timer classes here http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx.
Use Timer with as high pulling interval as you can afford, 1 sec, half a sec.
You need to tradeoff between CPU usage and the maximum delay you can afford between checks.
Let your loop sleep. It's running around and around and getting tired. At the very least, let it take a break eventually.
Because your function isn't doing anything inside the while block, it grabs the CPU, and, for all practical purposes, never lets go of it, so other threads can do their work
private void checkingData()
{
while (true)
{
// executes, immediately
}
}
If you change it to the following, you should see more reasonable CPU consumption:
private void checkingData()
{
while (true)
{
// read your sensor data
Thread.Sleep(1000);
}
}
you can use blocking queue. take a item from blocking queue will block the thread until there is a item put into the queue. that doesn't cost any cpu.
with .net4, you can use BlockingCollection http://msdn.microsoft.com/en-us/library/dd267312.aspx
under version 4, there is not blocking queue int .net framework.
you can find many implements of blocking queue if you google it.
here is a implementation
http://www.codeproject.com/KB/recipes/boundedblockingqueue.aspx
by the way. where does the data you wait come from?
EDIT
if you want to check file. you can use FileSystemWatcher to check it with thread block.
if your data comes from external API and the api doesn't block the thread, there is no way to block the thread except use Thread.Sleep
If you're polling for a condition, definitely do as others suggested and put in a sleep. I'd also add that if you need maximum performance, you can use a statistical trick to avoid sleeping when sensor data has been read. When you detect sensor data is idle, say, 10 times in a row, then start to sleep on each iteration again.

Alternative to StreamReader.Peek and Thread.Interrupt

Quick preface of what I'm trying to do. I want to start a process and start up two threads to monitor the stderr and stdin. Each thread chews off bits of the stream and then fires it out to a NetworkStream. If there is an error in either thread, both threads need to die immediately.
Each of these processes with stdout and stdin monitoring threads are spun off by a main server process. The reason this becomes tricky is because there can easily be 40 or 50 of these processes at any given time. Only during morning restart bursts are there ever more than 50 connections, but it really needs to be able to handle 100 or more. I test with 100 simultaneous connections.
try
{
StreamReader reader = this.myProcess.StandardOutput;
char[] buffer = new char[4096];
byte[] data;
int read;
while (reader.Peek() > -1 ) // This can block before stream is streamed to
{
read = reader.Read(buffer, 0, 4096);
data = Server.ClientEncoding.GetBytes(buffer, 0, read);
this.clientStream.Write(data, 0, data.Length); //ClientStream is a NetworkStream
}
}
catch (Exception err)
{
Utilities.ConsoleOut(string.Format("StdOut err for client {0} -- {1}", this.clientID, err));
this.ShutdownClient(true);
}
This code block is run in one Thread which is right now not Background. There is a similar thread for the StandardError stream. I am using this method instead of listening to OutputDataReceived and ErrorDataReceived because there was an issue in Mono that caused these events to not always fire properly and even though it appears to be fixed now I like that this method ensures I'm reading and writing everything sequentially.
ShutdownClient with True simply tries to kill both threads. Unfortunately the only way I have found to make this work is to use an interrupt on the stdErrThread and stdOutThread objects. Ideally peek would not block and I could just use a manual reset event to keep checking for new data on stdOut or stdIn and then just die when the event is flipped.
I doubt this is the best way to do it. Is there a way to execute this without using an Interrupt?
I'd like to change, because I just saw in my logs that I missed a ThreadInterruptException thrown inside Utlities.ConsoleOut. This just does a System.Console.Write if a static variable is true, but I guess this blocks somewhere.
Edits:
These threads are part of a parent Thread that is launched en masse by a server upon a request. Therefore I cannot set the StdOut and StdErr threads to background and kill the application. I could kill the parent thread from the main server, but this again would get sticky with Peek blocking.
Added info about this being a server.
Also I'm starting to realize a better Queuing method for queries might be the ultimate solution.
I can tell this whole mess stems from the fact that Peek blocks. You're really trying to fix something that is fundamentally broken in the framework and that is never easy (i.e. not a dirty hack). Personally, I would fix the root of the problem, which is the blocking Peek. Mono would've followed Microsoft's implementation and thus ends up with the same problem.
While I know exactly how to fix the problem should I be allowed to change the framework source code, the workaround is lengthy and time consuming.
But here goes.
Essentially, what Microsoft needs to do is change Process.StartWithCreateProcess such that standardOutput and standardError are both assigned a specialised type of StreamReader (e.g. PipeStreamReader).
In this PipeStreamReader, they need to override both ReadBuffer overloads (i.e. need to change both overloads to virtual in StreamReader first) such that prior to a read, PeekNamedPipe is called to do the actual peek. As it is at the moment, FileStream.Read() (called by Peek()) will block on pipe reads when no data is available for read. While a FileStream.Read() with 0 bytes works well on files, it doesn't work all that well on pipes. In fact, the .NET team missed an important part of the pipe documentation - PeekNamedPipe WinAPI.
The PeekNamedPipe function is similar to the ReadFile function with the following exceptions:
...
The function always returns immediately in a single-threaded application, even if there is no data in the pipe. The wait mode of a named pipe handle (blocking or nonblocking) has no effect on the function.
The best thing at this moment without this issue solved in the framework would be to roll out your own Process class (a thin wrapper around WinAPI would suffice).
Why dont you just set both Threads to be backround and then kill the app? It would cause an immediate closing of both threads.
You're building a server. You want to avoid blocking. The obvious solution is to use the asynchronous APIs:
var myProcess = Process.GetCurrentProcess();
StreamReader reader = myProcess.StandardOutput;
char[] buffer = new char[4096];
byte[] data;
int read;
while (!myProcess.HasExited)
{
read = await reader.ReadAsync(buffer, 0, 4096);
data = Server.ClientEncoding.GetBytes(buffer, 0, read);
await this.clientStream.WriteAsync(data, 0, data.Length);
}
No need to waste threads doing I/O work :)
Get rid of peek and use the method below to read from the process output streams. ReadLine() returns null when the process ends. To join this thread with your calling thread either wait for the process to end or kill the process yourself. ShutdownClient() should just Kill() the process which will cause the other thread reading the StdOut or StdErr to also exit.
private void ReadToEnd()
{
string nextLine;
while ((nextLine = stream.ReadLine()) != null)
{
output.WriteLine(nextLine);
}
}

C#: Handling terminate signal in TCP handler thread?

I am using the TcpClient class in C#.
Each time there is a new tcp connection request, the usual practice is to create a new thread to handle it. And it should be possible for the main thread to terminate these handler threads anytime.
My solution for each of these handler thread is as follows:
1 Check NetworkStream's DataAvailable method
1.1 If new data available then read and process new data
1.2 If end of stream then self terminate
2 Check for terminate signal from main thread
2.1 If terminate signal activated then self terminate
3 Goto 1.
The problem with this polling approach is that all of these handler threads will be taking up significant processor resources and especially so if there is a huge number of these threads. This makes it highly inefficient.
Is there a better way of doing this?
See Asynchronous Server Socket Example to learn how to do this the ".NET way", without creating new threads for each request.
Believe it or not that 1000 tick sleep will really keep things running smooth.
private readonly Queue<Socket> sockets = new Queue<Socket>();
private readonly object locker = new object();
private readonly TimeSpan sleepTimeSpan = new TimeSpan(1000);
private volatile Boolean terminate;
private void HandleRequests()
{
Socket socket = null;
while (!terminate)
{
lock (locker)
{
socket = null;
if (sockets.Count > 0)
{
socket = sockets.Dequeue();
}
}
if (socket != null)
{
// process
}
Thread.Sleep(sleepTimeSpan);
}
}
I remember working on a similar kind of Windows Service. It was a NTRIP Server that can take around 1000 TCP connections and route the data to a NTRIP Caster.
If you have a dedicated server for this application then it will not be a problem unless you add more code to each thread (File IO, Database etc - although in my case I also had Database processing to log the in/out for each connection).
The things to watch out for:
Bandwidth when the threads goes up to 600 or so. You will start seeing disconnections when the TCP Buffer window is choked for some reason or the available bandwidth falls short
The operating system on which you are running this application might have some restrictions, which can cause disconnections
The above might not be applicable in your case but I just wanted it put it here because I faced then during development.
You're right that you do not want all of your threads "busy waiting" (i.e. running a small loop over and over). You either want them blocking, or you want to use asynchronous I/O.
As John Saunders mentioned, asynchronous I/O is the "right way" to do this, since it can scale up to hundreds of connections. Basically, you call BeginRead() and pass it a callback function. BeginRead() returns immediately, and when data arrives, the callback function is invoked on a thread from the thread pool. The callback function processes the data, calls BeginRead() again, and then returns, which releases the thread back into the pool.
However, if you'll only be holding a handful of connections open at a time, it's perfectly fine to create a thread for each connection. Instead of checking the DataAvailable property in a loop, go ahead and call Read(). The thread will block, consuming no CPU, until data is available to read. If the connection is lost, or you close it from another thread, the Read() call will throw an exception, which you can handle by terminating your reader thread.

Categories

Resources