gpt4 book ai didi

c# - 为什么我的带有计时器的 C# Winforms 程序在一天后陷入停滞?

转载 作者:行者123 更新时间:2023-12-01 00:35:20 25 4
gpt4 key购买 nike

我有一个程序,每分钟使用来 self 们内部订单数据库的 MySQL 查询更新两个 DataGridView 对象,这样我们就可以跟踪旧订单并确保它们得到处理。

它运行良好,但如果您继续运行该程序,它会开始变得越来越慢,您会在大约一天后真正注意到它。重新启动程序可以解决此问题,但我真的很想知道为什么我不能让它继续运行。

这里是定时器代码和它调用的函数:

    private void timer1_Tick(object sender, EventArgs e)
{
UpdateOrderDisplay();
}

private void UpdateOrderDisplay()
{
grdOrderItems.Rows.Clear();
grdHoldOrders.Rows.Clear();
string strsql;
string CustomerName;
string MyConString = "SERVER=**********;" + "DATABASE=***********;" + "UID=************;" + "PASSWORD=***********;";
using (MySqlConnection connection = new MySqlConnection(MyConString))
{
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
strsql = "select * from orders where ship_reference=0 and OnHold =0 order by order_id asc";
command.CommandText = strsql;
connection.Open(); Reader = command.ExecuteReader();
while (Reader.Read())
{
if (Reader["payment_date"].ToString() != "")
{
if (Reader["custom"].ToString().Contains("~*"))
{
CustomerName = Reader["custom"].ToString().Substring(0, Reader["custom"].ToString().IndexOf("~"));
}
else
{
CustomerName = Reader["shipping_address_name"].ToString();
}
grdOrderItems.Invoke(new MethodInvoker(() => grdOrderItems.Rows.Add(Convert.ToDateTime(Reader["payment_date"].ToString().Substring(0, 21)).ToString(), Reader["txn_id"].ToString(), CustomerName, Reader["mc_gross"].ToString(), Reader["memo"].ToString(), Reader["order_id"].ToString())));
}
}
connection.Close();
strsql = "select * from orders where OnHold =1 order by order_id asc";
command.CommandText = strsql;
connection.Open(); Reader = command.ExecuteReader();
while (Reader.Read())
{
if (Reader["payment_date"].ToString() != "")
{
if (Reader["custom"].ToString().Contains("~*"))
{
CustomerName = Reader["custom"].ToString().Substring(0, Reader["custom"].ToString().IndexOf("~"));
}
else
{
CustomerName = Reader["shipping_address_name"].ToString();
}
grdHoldOrders.Invoke(new MethodInvoker(() => grdHoldOrders.Rows.Add(Convert.ToDateTime(Reader["payment_date"].ToString().Substring(0, 21)).ToString(), Reader["txn_id"].ToString(), CustomerName, Reader["mc_gross"].ToString(), Reader["memo"].ToString(), Reader["order_id"].ToString(),Reader["Hold_Review_Date"].ToString().Substring(0,Reader["Hold_Review_Date"].ToString().IndexOf(" ")),Reader["payer_email"].ToString())));
}
}





connection.Close();
}

}

此外,如果它是相关的,这里是一些我用来对 DataGridView 对象的行进行颜色编码的代码,这样我们就可以很容易地分辨出哪个顺序是旧的:

    private void grdOrderItems_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
grdOrderItems.RowPrePaint += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(this.grdOrderItems1_RowPrePaint);

}
private void grdOrderItems1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if (e.RowIndex <= grdOrderItems.Rows.Count - 1)
{
string StringNow = DateTime.Now.ToString();
string NowTime = StringNow.Substring(StringNow.IndexOf(" ")+1, StringNow.Length- StringNow.IndexOf(" ")-1);
string OrderDateTime = grdOrderItems.Rows[e.RowIndex].Cells[0].Value.ToString().Substring(0, grdOrderItems.Rows[e.RowIndex].Cells[0].Value.ToString().IndexOf(" ")+1) + NowTime;
if ((Convert.ToDateTime(StringNow) - Convert.ToDateTime(OrderDateTime)).Days > 2)
{
grdOrderItems.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Tomato;
}
else
{
if ((Convert.ToDateTime(StringNow) - Convert.ToDateTime(OrderDateTime)).Days > 1)
{
grdOrderItems.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Yellow;
}
else
{
if ((Convert.ToDateTime(StringNow) - Convert.ToDateTime(OrderDateTime)).Days > 0)
{
grdOrderItems.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Tan;
}

}
}
}
}

最佳答案

您可能有 MySqlDataReader 泄漏。处理完每个 Reader 对象后,将其处理掉。这是实现这一目标的好方法;它对异常具有弹性,并且 reader 变量在使用结束时超出范围。

    using (var reader = command.ExecuteReader()
{
while (reader.Read())
{
/* your per-row logic here */
}
}

您也可以使用 Close() 执行此操作:

    MySqlDataReader Reader; 
...
Reader = command.ExecuteReader()
while (Reader.Read())
{
/* your per-row logic here */
}
Reader.Close();

您正在关闭并重新打开每个查询的连接。那没有必要。打开它一次,将它用于两个查询,然后关闭它。

您可能会考虑让您的连接保持打开状态的时间超过单个计时器滴答声。 (如果您有连接池,请忽略此建议。)

使用任务管理器查看您的程序占用了多少 cpu% 和内存(早上和晚上再次)。如果内存在增长,则说明存在某种泄漏。如果 cpu% 正在增长,则表示您正在进行某种列表处理,其中列表随着每次滴答而变长。

关于c# - 为什么我的带有计时器的 C# Winforms 程序在一天后陷入停滞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53287079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com