Reputation: 45
I'm writing an C# Windows apps to fetch input from serial port, and I refer a sample code as shown below:
private void serialPort_DataReceived_1 (object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (this.serialPort.IsOpen == true)
{
this.BeginInvoke(new EventHandler(delegate { this.textBox1.AppendText(this.serialPort.ReadExisting()); }));
}
}
The code works well. But I just wonder if the BeginInvoke running many times, would it create also many "new EventHandler" in memory which is no used after this?
Upvotes: 3
Views: 127
Reputation: 941635
Some back of the envelope calculations. A serial port runs at 115,000 baud tops, that's 11,500 bytes per second max. The absolute worst case is having DataReceived fire for each individual byte, technically possible although that will come to a very poor end given the overhead of Control.BeginInvoke(). Something you'll have to fix.
A delegate object requires 32 bytes for the 32-bit version of the CLR. You'll thus consume at most 11,500 x 32 = 368 KB/sec of heap memory. This is all allocated in the generation 0 heap and almost guaranteed to be completely removed by a gen 0 garbage collection since the delegate objects live for such a short time.
The default gen #0 heap size is 2 megabytes. It will grow when the heap is under pressure, going up to 8 megabytes or more when gen 0 collection often move objects to gen 1. Not likely in this case since the delegate objects are so short-lived. Let's work with 2 megabytes.
It thus takes 2048 / 368 = 5.4 seconds for the gen 0 heap to get filled by just the delegate objects and trigger a garbage collection. A gen 0 collection takes on average 5 milliseconds although you're very unlikely to need that much since there are so few surviving objects that need to be moved.
The percentage of processing time spent on collection for these objects is thus 0.005 / 5.4 = 0.09% worst case.
This is not observable.
Upvotes: 3
Reputation: 83356
Each of those anonymous delegates will be eligible for garbage collection once they complete, so it's probably not a big deal.
If you're really worried about it, you could always create a single EventHandler as a class field:
EventHandler readFromSerialHandler;
And then in your constructor set it to
readFromSerialHandler = (s, e) =>
this.textBox1.AppendText(this.serialPort.ReadExisting());
So now your DataReceived handler would simply be:
private void serialPort_DataReceived_1 (object sender, SerialDataReceivedEventArgs e) {
if (this.serialPort.IsOpen == true) {
this.BeginInvoke(this.readFromSerialHandler);
}
}
Upvotes: 3