C# 创建新实例还是覆盖?
我正在使用SQLServer数据库创建一个C Winform应用程序,在任何形式下,我都在form类中声明一个SqlCOnnection和一个SqlCommand,但在需要时,我开始在每个方法中初始化。 这是我的代码:C# 创建新实例还是覆盖?,c#,performance,memory,instance,C#,Performance,Memory,Instance,我正在使用SQLServer数据库创建一个C Winform应用程序,在任何形式下,我都在form类中声明一个SqlCOnnection和一个SqlCommand,但在需要时,我开始在每个方法中初始化。 这是我的代码: public partial class DrinkIncomeForm : Form { #region Class Variables private string conString; private str
public partial class DrinkIncomeForm : Form
{
#region Class Variables
private string conString;
private string queryP1;
private string queryP2;
private SqlConnection con;
private SqlCommand cmd;
private SqlDataAdapter myAdapter;
private SqlDataReader myReader;
private DataTable drinksIncomeTable;
#endregion
public DrinkIncomeForm()
{
InitializeComponent();
}
private void DrinkIncomeForm_Load(object sender, EventArgs e)
{
conString = System.Configuration.ConfigurationManager.ConnectionStrings["MyGymConString"].ConnectionString;
LoadDrinksCombo();
LoadCashierCombo();
DrinkComBox.SelectedIndex = 0;
CashierComBox.SelectedIndex = 0;
LoadDrinksIncomeDGV();
}
private void DrinkComBox_SelectedIndexChanged(object sender, EventArgs e)
{
LoadDrinksIncomeDGV();
}
private void CashierComBox_SelectedIndexChanged(object sender, EventArgs e)
{
LoadDrinksIncomeDGV();
}
private void LoadDrinksIncomeDGV()
{
con = new SqlConnection(conString);
cmd = new SqlCommand();
cmd.Connection = con;
queryP1 = "select TransID, DrinkName, Quantity, Price, Offer, format(TransDate, 'dd/MM/yyyy hh:mm:ss')as TransDate, Cashier from tblDrinksIncome ";
queryP2 = " where 1=1 ";
try
{
con.Open();
cmd.Parameters.Clear();
if(DrinkComBox.SelectedIndex >0)
{
queryP2 += " AND DrinkName=@drinkname";
cmd.Parameters.AddWithValue("@drinkname", DrinkComBox.SelectedItem.ToString());
}
if (CashierComBox.SelectedIndex >0)
{
queryP2 += " AND Cashier=@cashier";
cmd.Parameters.AddWithValue("@cashier", CashierComBox.SelectedItem.ToString());
}
cmd.CommandText = "" + queryP1 + queryP2;
myAdapter = new SqlDataAdapter(cmd);
drinksIncomeTable = new DataTable();
myAdapter.Fill(drinksIncomeTable);
DrinksIncomeDGV.DataSource = drinksIncomeTable;
con.Close();
}
catch
{
con.Close();
MessageBox.Show("Database Error.");
}
}
}
正如您在每次用户从组合框中选择过滤器时看到的,将创建新实例。
我的问题是,这会对记忆和性能产生不良影响,如果是这样,有什么更好的方法可以做到这一点?
谢谢:它的性能可能会略有下降,但它的设计很好
但不应将连接存储在成员变量中。但仅限于局部变量。最好是usingvar s=newsqlconnection。。。通过这种方式,您可以确保连接在方法末尾被释放,并且对它的任何引用都应该丢失,这样就可以对其进行垃圾收集。这同样适用于SqlCommand
所以,您唯一的关键错误,不是调用Dispose,而是调用only Close。什么实例?i、 与你有关的事情是什么?实际上,这不太可能成为任何非内循环数据处理场景的问题。因为这看起来是UI绑定的,所以我甚至不会去看它——与其他正在发生的事情相比,它将是无关紧要的。它能被优化吗?当然这有关系吗?一点也不可能。如果你想知道:测量它。如果这真的很重要,那可能意味着你向用户显示了太多有用的数据,所以:显示更少的数据!如果事实证明这很重要,我要说的第一件事是:停止使用DataTable。这对提高效率并没有任何帮助,我关心的是DataTable、SqlConnection和SqlCommand的实例。每次用户更改过滤器时,函数LoadProductsIncome都会创建新实例,我不知道旧实例会发生什么!我可以用什么来代替DataTable呢?现在,一些POCO T的列表通常是一个安全的赌注——即列表、列表或其他什么;也许可以看看Dapper,了解如何在不编写代码的情况下实际填充它。不要在每次调用时创建新的SqlConnection,使用单例模式,或者在表单打开时保持连接打开。每次创建一个新的SqlCommand是可以的,但不应该将连接存储在成员变量中。但仅限于局部变量这是高度上下文和主观的;这两种方法都是有效的,具体取决于场景。当然,如果您每次都要新建它,那么我100%同意您的看法,实例字段只有在被重用时才有意义。同意这个命令,但是:我可能会说,如果你直接接触命令API,你就做错了:@marcGravel Good,你更准确。保持连接打开与否实际上取决于上下文。对于性能问题:每次新的测试都会比较慢。我只是想指出,您必须在性能和软件架构之间做出妥协。如果你意识到这一点,一切都很好。如果采用异步方式,则每个线程(通常是每个方法)一个连接是更安全的方式。如果采用异步方式,则需要停止考虑线程:但从根本上说:无论使用同步还是异步方式,连接的并发共享都会断开;因此,请同意,如果您要并发,您需要作用域连接-我只是不认为同步与异步是重要的。因此,我担心旧实例会发生什么,我不确定它是否会被收集!现在在关闭后调用Dispose会有意义吗?这不是一个确定的决定,保持连接打开与否更好。但至少,要改进您当前的解决方案,请调用dispose,不要将连接存储在您的私有字段中!它不会被垃圾收集,只要它被储存。