我有这个代码,每次都是"主菜单"单击项目。它基本上填充了一个子菜单堆栈面板" buttoned"用户控制。
private void LoadSubMenuControls(int _menuid)
{
double _itemcount = 0;
double _buttonHeight = 61;
//fill out user permissions
//get information from users
//release events and bindintgs
foreach (Object _child in Midmenu.Children)
{
((MenuButton)_child).MidMousePressed -= new MenuButton.MidMenuMouseButtonPressed(MenuButton_MidMousePressed);
((MenuButton)_child).DataContext = null;
}
Midmenu.Children.Clear();
midScroll1.ScrollToTop();
Midmenu.Height = MidHeight;
Midmenu.Width = this.Width / 3;
foreach (DataRow _row in _rxworksmenues.GetMenuItems(_menuid))
{
_itemcount++;
MainScreenWPFUC.MenuButtonViewModel _butview = new MenuButtonViewModel();
_butview.ApplyViewModel(_row,_itemcount);
_butview.MenuButton.DataContext = _butview;
_butview.MenuButton.Height = _buttonheight;
_butview.MenuButton.Width = Midmenu.Width;
_butview.MenuButton.MidMousePressed += new MenuButton.MidMenuMouseButtonPressed(MenuButton_MidMousePressed);
Midmenu.Children.Add(_butview.MenuButton);
Midmenu.UpdateLayout();
}
//When there are more items than height allows display the
//scrolbar and hide the border
//also squeeze the midframe to accomodate scrollbar with width of 56 px
if (MidHeight < _rxworksmenues.CountMenuItems(_menuid) * _buttonHeight)
{
midScroll1.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
Midmenu.ScrollOwner = midScroll1;
Midmenu.Width = this.Width /3 - 56;
ScrollViewerBorder.BorderThickness = new Thickness(1,0,0,0);
}
else
{
midScroll1.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
ScrollViewerBorder.BorderThickness = new Thickness(1,0,1,0);
}
//TFS 10560
//Forces garbage collection to rpevent memory link occuring in this function
//System.Threading.Thread.Sleep(200);
//GC.Collect();
//GC.WaitForPendingFinalizers();
}
我发现的事情是,每次执行此代码时,进程中的内存会上升几个K并且永远不会让人失望。我从阅读中发现的是,强制垃圾收集可以提供帮助,但确实如此,但我也认为这不是一个好的做法,并且想要找到实际发生泄漏的地方。
要说明问题,如何捕获泄漏,代码是否是原因?
谢谢。
GetMenuItems来自这个类。
public class Menues
{
private DataTable _table = new DataTable("menues");
public Menues()
{
}
public void Fill(int sysuserid, string dbconnection)
{
// DateTime start = new DateTime(DateTime.Now.Ticks);
SqlConnection _conn = new SqlConnection( dbconnection);
SqlCommand _comm = new SqlCommand("Get_RxWorks_Menues",_conn);
_comm.CommandType = CommandType.StoredProcedure;
SqlParameter _param = new SqlParameter("@sysuserid",sysuserid);
_comm.Parameters.Add(_param);
SqlDataAdapter _da = new SqlDataAdapter(_comm);
_da.Fill(_table);
// DateTime end = new DateTime(DateTime.Now.Ticks);
// MessageBox.Show(end.Subtract(start).TotalMilliseconds.ToString());
}
/// <summary>
/// Fetches main menu items when parentid is ommited
/// or submenu items when int parentid is specified
/// </summary>
/// <returns></returns>
public DataRow[] GetMenuItems()
{
return _table.Select("parentid=0");
}
/// <summary>
/// Fetches main menu items when parentid is ommited
/// or submenu items when int parentid is specified
/// </summary>
/// <returns></returns>
public DataRow[] GetMenuItems(int parentid)
{
return _table.Select("parentid=" + parentid);
}
/// <summary>
/// Returns number of menu items, when empty returns left menu
/// </summary>
/// <returns></returns>
public int CountMenuItems()
{
return _table.Select("parentid=0").Length;
}
/// <summary>
/// Returns number of menu items, when empty returns left menu
/// </summary>
/// <returns></returns>
public int CountMenuItems(int parentid)
{
return _table.Select("parentid=" + parentid).Length;
}
public DataTable MenuTable
{
get
{
return _table;
}
}
答案 0 :(得分:0)
在您的代码中:
public void Fill(int sysuserid, string dbconnection)
{
// DateTime start = new DateTime(DateTime.Now.Ticks);
SqlConnection _conn = new SqlConnection( dbconnection);
SqlCommand _comm = new SqlCommand("Get_RxWorks_Menues",_conn);
_comm.CommandType = CommandType.StoredProcedure;
SqlParameter _param = new SqlParameter("@sysuserid",sysuserid);
_comm.Parameters.Add(_param);
SqlDataAdapter _da = new SqlDataAdapter(_comm);
_da.Fill(_table);
// DateTime end = new DateTime(DateTime.Now.Ticks);
// MessageBox.Show(end.Subtract(start).TotalMilliseconds.ToString());
}
SqlConnection未关闭。如果SqlConnection超出范围,则不会被关闭。因此,您必须通过调用Close或Dispose显式关闭连接。关闭和处置在功能上是等效的。
如果连接池值Pooling设置为true或yes,则将基础连接返回到连接池。另一方面,如果Pooling设置为false或no,则实际上将关闭与服务器的基础连接。
这可能是内存增加的原因。
要正确使用SqlConnection,您可以按照以下步骤操作:
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Do work here; connection closed on following line.
}
请阅读MSDN了解详情
请同时检查您使用的UI对象是否应明确处理,因为UI对象将分配本机句柄。