I have a simple project, using MVC pattern, ET and WCF. It uses Dijkstra to find paths between cities. This is the class itself.
However, when calling FindPathFromCityToCity() with two same lists in the map object, same from and to, when it's on a normal console application it returns the desired result. However, when used from WCF, it fails on line 39 with exception System.Collections.Generic.KeyNotFoundException.
In order to check whether if my input is incorrect I added that writing to a txt file (line 17 to 27) and this is what it results (TL;DR - both are exactly the same):
Console:
COUNT: 14 - RANGE 120
FROM: Aalborg - TO: Copenhagen
C: Frederikshavn - E: 2 - T: BLL.BatteryCenter
C: Aalborg - E: 6 - T: BLL.BatteryCenter
C: Hobro - E: 4 - T: BLL.BatteryCenter
C: Randers - E: 6 - T: BLL.BatteryCenter
C: Viborg - E: 8 - T: BLL.BatteryCenter
C: Aarhus - E: 8 - T: BLL.BatteryCenter
C: Herning - E: 6 - T: BLL.BatteryCenter
C: Vejle - E: 8 - T: BLL.BatteryCenter
C: Kolding - E: 6 - T: BLL.BatteryCenter
C: Odense - E: 6 - T: BLL.BatteryCenter
C: Aabenraa - E: 2 - T: BLL.BatteryCenter
C: Koge - E: 4 - T: BLL.BatteryCenter
C: Copenhagen - E: 2 - T: BLL.BatteryCenter
C: Soro - E: 4 - T: BLL.BatteryCenter
WCF:
COUNT: 14 - RANGE 120
FROM: Aalborg - TO: Copenhagen
C: Frederikshavn - E: 2 - T: BLL.BatteryCenter
C: Aalborg - E: 6 - T: BLL.BatteryCenter
C: Hobro - E: 4 - T: BLL.BatteryCenter
C: Randers - E: 6 - T: BLL.BatteryCenter
C: Viborg - E: 8 - T: BLL.BatteryCenter
C: Aarhus - E: 8 - T: BLL.BatteryCenter
C: Herning - E: 6 - T: BLL.BatteryCenter
C: Vejle - E: 8 - T: BLL.BatteryCenter
C: Kolding - E: 6 - T: BLL.BatteryCenter
C: Odense - E: 6 - T: BLL.BatteryCenter
C: Aabenraa - E: 2 - T: BLL.BatteryCenter
C: Koge - E: 4 - T: BLL.BatteryCenter
C: Copenhagen - E: 2 - T: BLL.BatteryCenter
C: Soro - E: 4 - T: BLL.BatteryCenter
Can someone see any reason for that to happen?
EDIT:
I did further tests, printing everything possible of the objects with this snippet and there is no difference in the objects (except hash of course):
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\log\check.txt", true))
{
foreach (var m in map.Stations)
{
file.WriteLine(" --- {0} - {1} - {2} - {3} --- ", m.name, m.Edgelist.Count, m.GetType(), m.GetHashCode());
foreach(var e in m.Edgelist)
{
file.WriteLine();
file.WriteLine(" # {0} - {1} - {2} - {3}", e.BatteryStation.name, e.BatteryStation1.name, e.distance, e.edgeID);
file.WriteLine(" + {0} - {1} - {2}", e.BatteryStation.GetType(), e.BatteryStation.stationID, e.BatteryStation.GetHashCode());
file.WriteLine(" - {0} - {1} - {2}", e.BatteryStation1.GetType(), e.BatteryStation1.stationID, e.BatteryStation1.GetHashCode());
}
file.WriteLine();
}
}
This all hinges on the mechanics of the
BatteryCenterobject.The calling code is passing it in as a parameter, and the function is using it as a key in the map.
Have you overridden the functions
EqualsandGetHashCodeonBatteryCenter?If not, then the dictionary lookup will be searching for that exact object. Not a
BatteryCenterwith all of the same fields, but the object with the same reference.The WCF client would be passing in an equivalent but nonetheless different
BatteryCenter, which the dictionary is failing to find.Once you add overrides for
BatteryCenter.EqualsandBatteryCenter.GetHashCodethis would probably work.eg