I have developed a Point of Sale system using C#, Winforms and Mysql. After its deployment, I observed that the memory size keeps on increasing with time. After evaluating my code, I felt my Data Layer might be the culprit. I have generalized database call using methods like these
public static DataTable ExecQuery(string query, List<SqlParam> sp_params, string db)
{
MySqlConnection sCon = new MySqlConnection();
sCon.ConnectionString = "server=" + server + ";port=" + port + ";database=" + db + ";uid=" + user + ";pwd=" + password + ";charset=utf8;";
MySqlCommand command = new MySqlCommand();
command.CommandType = CommandType.Text;
command.Connection = sCon;
if (sp_params != null)
{
for (int i = 0; i < sp_params.Count; i++)
{
MySqlParameter sparam = new MySqlParameter();
sparam.ParameterName = sp_params[i].Name;
sparam.MySqlDbType = sp_params[i].Type;
sparam.Value = sp_params[i].Value;
command.Parameters.Add(sparam);
}
}
command.CommandText = query;
sCon.Open();
MySqlDataReader sd = command.ExecuteReader();
DataTable dt = new DataTable();
for (int fc = 0; fc < sd.FieldCount; fc++)
{
if (dt.Columns.Contains(sd.GetName(fc)))
{
dt.Columns.Add(sd.GetName(fc) + "1", sd.GetFieldType(fc));
}
else
{
dt.Columns.Add(sd.GetName(fc), sd.GetFieldType(fc));
}
}
while (sd.Read())
{
DataRow dr = dt.NewRow();
for (int fc = 0; fc < sd.FieldCount; fc++)
{
dr[fc] = sd.GetValue(fc);
}
dt.Rows.Add(dr);
}
sCon.Close();
return dt;
}
For every database call, We use this method. The front end has to only specify parameters and query. Am I right in my suspicion that this static method is causing memory problems?
Update:
Just found another leak in my App:
Wherever reportviewer is used, LocalReport.ReleaseSandboxAppDomain() must be called in host form's formclosing event. Otherwise each invocation of Report, adds to memory size.
Update 2
Found the actual cause of Memory Leak in my system. I am Using a complex usercontrol which I add in a flowlayoutpanel.
I was using a normal foreach loop to dispose each control.. but somehow only half objects were disposed. I nested this foreach loop inside a for loop with counter as number of controls.
int count = flwControls.Controls.Count;
for (int i = 0; i < count; i++)
{
foreach (Control c in flwControls.Controls)
{
c.Dispose();
}
}