c# Memory leak system.timers
本文关键字:timers system leak Memory | 更新日期: 2023-09-27 18:34:32
我目前正在编写一个与I/O设备交互的程序,并且需要一种每x秒轮询一次设备的方法,以便检查输入/输出连接。为此,我使用了一个按钮,该按钮使用计时器和计时器事件句柄创建一个线程来执行轮询。但是,我注意到在任务管理器中,随着时间的推移,它会慢慢消耗更多内存。下面是一些(我认为(与我的问题相关的代码片段。
用于创建线程的按钮:
private void btnConnect_Click(object sender, EventArgs e)
{
new Thread(start).Start();
}
包含计时器的线程:
public void start()
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timerElapsed);
timer.Enabled = true;
}
已过事件处理程序:
public void timerElapsed(object sender, ElapsedEventArgs e)
{
connect();
}
最后是方法connect((;:
public void connect()
{
StringBuilder sb = new StringBuilder();
sb.Append(txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text);
int Port = int.Parse(txtPort.Text);
string address = sb.ToString();
//send data
byte[] bData = new byte[71];
bData[0] = 240;
bData[1] = 240;
bData[2] = 0;
bData[3] = 1;
bData[68] = 240;
bData[69] = 240;
bData[70] = this.CalculateCheckSum(bData);
try
{
byte[] result = this.SendCommandResult(address, Port, bData, 72);
if (result != null)
{
this.Invoke((MethodInvoker)delegate
{
txtOutput1.Text = (result[4] == 0x00 ? "HIGH" : "LOW"); // runs on UI thread
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
我很确定泄漏要么来自计时器,要么来自方法connect((;中使用的匿名委托,有人有任何想法吗?
每次单击按钮时都会创建一个新的计时器。 此外,您没有保留对它的引用,因此它将被垃圾回收器销毁。 无需在新线程上启动计时器,因为计时器将在新线程上引发 Elapsed 事件。
class Form1 ...
{
private System.Timers.Timer timer = null;
public void start()
{
if (timer == null)
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timerElapsed);
}
timer.Enabled = true;
}
...
}
就内存泄漏而言,我不会仅仅因为您看到应用程序运行时内存使用情况看似随机波动而假设存在内存泄漏。 这是在 .NET 等复杂框架中运行时的正常行为。 每次计时器触发时,它都会调用 connect 方法来创建新对象。这些对象将保留在内存中,直到垃圾回收器清理它们。因此,看到记忆爬升,然后在几分钟后突然又下降,一点也不奇怪。我不会怀疑问题,除非它在更长的时间内不断失控。
使用StringBuilder类的方式也很奇怪。 你在做什么:
StringBuilder sb = new StringBuilder();
sb.Append(txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text);
string address = sb.ToString();
没有比这样做更好(实际上它更糟(:
string address = txtIPseg1.Text + "." + txtIPseg2.Text + "." + txtIPseg3.Text + "." + txtIPseg4.Text;
如果您正在寻找一种更高效,可能更容易阅读的方法,请尝试这样的事情
string address = string.Format("{0}.{1}.{2}.{3}", txtIPseg1.Text, txtIPseg2.Text, txtIPseg3.Text, txtIPseg4.Text);
然而,没有什么东西会像任何会导致内存泄漏的东西一样跳出来,所以除非你有充分的理由这么想,否则我不会担心它。