2

Since I can't find any control to use as a LED indicator on my winform for my serial communication transmit and receive, I created my own user-defined indicator from label. It basically sets and resets the color of a label from black to lime for receive and black to red for transmit repeatedly. Its class is as follows. However, my .NET program seem to run for couple of hours and crash completely. When I view the details for crash error, windows reports it as clr20r3 error. I've had a similar issue when I wrote and developed a program under fedora linux. My serial communication indicator on a form somehow caused memory leak and crashed the program and when it was removed it worked flawlessly.

So, can you have memory leak from setting and resetting backcolor of a label repeatedly within seconds?

namespace SerialLED;

interface

uses
  System.Collections.Generic,
  System.Windows.Forms,
  System.Drawing.*,
  System.Text;

type

  TheLED = public class(Label)
  private
  protected
  public
    constructor;
  end;

  TSerialIndicator = public class
  private
    method TxTimerEvent(Sender:System.Object; e:System.EventArgs);
    method RxTimerEvent(Sender:System.Object; e:System.EventArgs);
  public
    Txlight:TheLED;
    Rxlight:TheLED;
    TxTimer:System.Timers.Timer;
    RxTimer:System.Timers.Timer;
    constructor(mform:Form);
    method Transmit;
    method Receive;
  end;

implementation

method TSerialIndicator.Transmit;
begin
  TxLight.BackColor := Color.Red;
  if TxTimer.Enabled = false then
     TxTimer.Enabled:=true;
end;

method TSerialIndicator.Receive;
begin
  RxLight.BackColor := Color.Lime;

  if RxTimer.Enabled=false then
    RxTimer.Enabled:=true;
end;

method TSerialIndicator.RxTimerEvent(Sender:System.Object; e:System.EventArgs);
begin
    RxLight.BackColor := Color.Black;
    RxTimer.Enabled:=false;
end;

method TSerialIndicator.TxTimerEvent(Sender:System.Object; e:System.EventArgs);
begin
    TxLight.BackColor := Color.Black;
    TxTimer.Enabled:=false;
end;

constructor TSerialIndicator(mform:Form);
begin
    RxLight := new TheLED;
    TxLight := new TheLED;

    TxLight.AutoSize := false;
    RxLight.AutoSize := false;

    TxLight.BorderStyle := BorderStyle.Fixed3D;
    RxLight.BorderStyle := BorderStyle.Fixed3D;

    TxLight.Location := new point(52,163);
    RxLight.Location := new point(82,163);

    TxLight.Width := 20;
    TxLight.Height := 20;
    RxLight.Width :=20;
    RxLight.Height := 20;

    mform.Controls.Add(RxLight);
    mform.Controls.Add(TxLight);

    RxTimer := new System.Timers.Timer;
    TxTimer := new System.Timers.Timer;
    RxTimer.Interval:=50;
    TxTimer.Interval:=50;
    RxTimer.Enabled:=false;
    TxTimer.Enabled:=false;
    RxTimer.Elapsed += new System.Timers.ElapsedEventHandler(@RxTimerEvent);
    TxTimer.Elapsed += new System.Timers.ElapsedEventHandler(@TxTimerEvent);

    RxLight.BackColor := Color.Black;
    TxLight.BackColor := Color.Black;
end;

constructor TheLED;
begin
  self.DoubleBuffered:=true;
end;

This is how it looks on a winform: enter image description here

ThN
  • 3,235
  • 3
  • 57
  • 115
  • 1
    `clr203r` does not mean `color`. It's `Common Language Runtime`, and a quick Google search on `clr203r error` found several hits that might help. – Ken White Dec 19 '12 at 15:07
  • 1
    Improve your error handling. Write an event handler for AppDomain.CurrentDomain.UnhandledException and log or display the value of e.ExceptionObject.ToString(). Now you *know* why and where it crashes. – Hans Passant Dec 19 '12 at 15:36
  • 1
    And don't use Systems.Timer.Timer, it has nasty threading behavior. Assigning the BackColor property from its Elapsed event handler is formally forbidden. Not disposing them is lethal, they keep on ticking when your UI is gone. There no point in avoiding System.Windows.Forms.Timer. – Hans Passant Dec 19 '12 at 15:40
  • @HansPassant, there was a reason why I used System.Timer.Timer and that takes us back to this stackoverflow question. http://stackoverflow.com/questions/13312164/why-timer-system-windows-forms-timer-wont-start – ThN Dec 19 '12 at 16:24
  • It is chronically difficult to help you, you keep ignoring advice. It certainly never said to use System.Timers.Timer, I said `Use Control.Begin/Invoke()` – Hans Passant Dec 19 '12 at 16:28
  • @HansPassant and others, I have changed my TSerialIndicator class and using the System.Windows.form.Timer on a winform, which will be closed after its use for my application to run. Therefore, the timer on the winform won't `TICK`. Am I right? That's what I am noticing. It only works once and no more. By the way, I apologize if I am chronically difficult to be helped. I am still learning as I am programming. It seems there is just so many holes in .NET programming. – ThN Dec 20 '12 at 13:51
  • I am totally lost after Hans comment about system.Timers.Timer not being reliable. At this point in time, I have done every that is to do but my timer won't TICK at all. My situation is just like this question - http://stackoverflow.com/questions/725735/how-to-enable-a-timer-from-a-different-thread-class – ThN Dec 21 '12 at 14:03

1 Answers1

0

Since no one wants to answer and I have solved my issue, I will answer this question myself.

Yes, it can lead to memory leak from what I have experienced and it depends how you set the backcolor for your control. If your control is not placed on the winform, then setting and resetting backcolor within short amount of time can lead to memory leak as Hans Passant has said. So, I followed his advice.

Basically I placed my control right on the winform and from my thread, I set and reset the backcolor. So far it has worked. I have been running my program for the last 5 days nonstop and it hasn't crashed or lost control.

ThN
  • 3,235
  • 3
  • 57
  • 115