This problem really baffeled me today. I'm working in Visual studio 2012, C# .net 4 app (Not sure if it matters).
I have some datatables that have multiple results in them. To figure out the best one to pick I'm looking for the one with the best Jaro-Winkler score, and sending that one back.
I sort the table results by making a dataview and in an attempt to properly dispose my data elements, I've wrapped the dataview in a using statment. The code looks like this:
public static DataRow getBestCandidate(DataTable searchTable, string searchName)
{
if (searchTable.Rows.Count == 1) //Nothing to do if there's only one row
{
return searchTable.Rows[0];
}
int tableSize = searchTable.Rows.Count;
for (int i = 0; i < tableSize; i++)
{
//Iterate through each entry and record the Jaro distance between our original search term.
searchTable.Rows[i][7] = jaro.getScrubbedDistance(searchTable.Rows[i][1].ToString(), searchName);
}
using (DataView dv = searchTable.DefaultView) //Sort the results
{
dv.Sort = "JaroDistance desc";
return dv[0].Row; //Send back the result with the highest Jaro score.
}
}
Here's what's weird. The first time I call this, it works just fine. Exactly as I want it to. If I call it twice in a row from the same method, it almost works the second time. When running a trace it gets all the way to the line "return dv[0].Row; " and when it goes to execute that, the object DV is null. It behaves exactly like the object was disposed of before I was done with it. This ends up killing that thread with an exception.
I took out the using statement and replaced it with this:
DataView dv = searchTable.DefaultView;
dv.Sort = "JaroDistance desc";
return dv[0].Row;
Then it works just fine. Hammering the methods didn't seem to cause huge memory spikes.
Is the using wrapper even needed? Why is it becoming null right before I return it?
Assuming the searchTable
is the same instance, you are disposing of its DefaultView
, an object you are sharing each time you call the method.
The using
isn't necessary here, but rather around searchTable
in whatever parent method manages that object.