I wrote an app that pulls a MS Access DB into a DataTable
and then displays it into a WPF datagrid. The dialog window has a search button which calls on a class that does the DB work.
The methods in play of the search window:
private void ExitBtn_Click(object sender, MouseButtonEventArgs e)
{
quoteheaders.Dispose();
GC.Collect();
Close();
}
private void TitleBar_DblClick(object sender, MouseButtonEventArgs e)
{
if (this.WindowState == WindowState.Normal) { this.WindowState = WindowState.Maximized; return; }
if (this.WindowState == WindowState.Maximized) { this.WindowState = WindowState.Normal; return; }
}
private void TitleBar_Click(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) { DragMove(); }
}
private Task<DataTable> Poll_QuoteHeader()
{
return Task.Run(() => SQLinterface.FindQuoteID(dbPath));
}
private async void SearchBtn_Click(object sender, RoutedEventArgs e)
{
quoteheaders = SQLinterface.FindQuoteID(dbPath);
quoteheaders = await Poll_QuoteHeader();
foundQuotes.ItemsSource = quoteheaders.AsDataView();
}
The class that talks to the database:
namespace QuoteClient
{
class SQLinterface
{
public DataTable FindServer()
{
DataTable SQLservers = new DataTable();
SqlDataSourceEnumerator SQLinstances = SqlDataSourceEnumerator.Instance;
SQLservers = SQLinstances.GetDataSources();
return SQLservers;
}
public DataTable FindQuoteID(string dbPath)
{
using(DataTable quoteID = new DataTable())
{
using (OleDbConnection quoteIDconn = new OleDbConnection(dbPath))
{
OleDbDataAdapter quoteIDadapter = new OleDbDataAdapter("SELECT * FROM DocumentHeaders", quoteIDconn);
quoteIDadapter.Fill(quoteID);
return quoteID;
}
}
}
}
}
I'm bringing this here because I would like to know if it is OK to use GC.Collect()
in this case. The app works fine without forcing a collection, but increases in memory every time the window is opened and search button is clicked. I am undecided on whether this is an actual leak or just the GC taking its time to cleanup.
So in short is there a better way to ensure that the memory that is used for filling the data table is disposed of? (I dispose of them either via using
or .Dispose()
)
Should I just leave the collection call since I know that when this window is closed nothing that was in use is needed anymore?
Or am I doing something wrong all around?
ItemsSource
in code-behind. \$\endgroup\$ItemSource
in code behind is not related to the memory usage I am seeing and learning how to handle. It happens when I do not show the data but only load it into aDataTable
\$\endgroup\$quoteID
that you dispose with ausing
. This does not make any sense. \$\endgroup\$DataTable
. It works. I suppose thats an improvement i can make to just use the first one, but i had trouble getting it to work properly with the asynchronousTask <DataTable>
method \$\endgroup\$Dispose
doesn't actually do much forDataTable.
. Also @t3chb0t is right: you dispose of thequoteID
when you return fromFindQuoteID
- that's wrong. It happens to work becauseDispose
doesn't do much forDataTable
but it's still wrong to do it. And you can't "free" memory in C#. TheDispose
pattern in C# primarily exists to release unmanaged resources and not to release memory. There are very very few situations in which callingGC.Collect()
might make sense but I don't think this is one of them. \$\endgroup\$