【发布时间】:2012-06-08 11:40:14
【问题描述】:
我使用自己的 IComparer 对列表进行排序,并且在运行应用程序(XNA 游戏)超过一个小时时效果很好。但是,突然之间,在使用自定义比较器调用排序方法时,有时会出现以下错误:
An unhandled exception of type 'System.ArgumentException' occured in mscorlib.dll
Additional Information: ArgumentException
这是抛出异常的那一行:
List<Continent> markets = new List<Continent>();
// filling the markets list ...
markets.Sort(new MarketCostCoverComparer(this));
这是我实现 IComparer 接口的类:
class MarketCostCoverComparer : IComparer<Continent> {
private Player player;
public MarketCostCoverComparer(Player player) {
this.player=player;
}
public int Compare(Continent c1, Continent c2) {
if(player.GetCostCovering(c1)<player.GetCostCovering(c2)) {
return +1;
} else if(player.GetCostCovering(c1)==player.GetCostCovering(c2)) {
return 0;
} else {
return -1;
}
}
}
这里有一些链接到比较器的方法...:
public float GetCostCovering(Continent continent) {
// cover<1 => bad | cover>1 => good
if(GetOilfieldTheoreticOutput(continent.Type, true)<continent.Economy.CurrentDemand) {
return ((float)((GetOilfieldTheoreticOutput(continent.Type, true)*continent.Economy.CurrentPrice)))/(float)GetOilfieldCosts(continent.Type, true);
} else {
return ((float)((continent.Economy.CurrentDemand*continent.Economy.CurrentPrice)))/(float)GetOilfieldCosts(continent.Type, true);
}
}
public int GetOilfieldTheoreticOutput(ContinentType continent, bool drilled) {
int total = 0;
foreach(Oilfield oilfield in worldmap.Continents[(int)continent].Oilfields) {
if(oilfield.Owner==this && oilfield.Drilled==drilled) {
total+=oilfield.TheoreticOutput;
}
}
return total;
}
public int GetOilfieldCosts(ContinentType continent, bool drilled) {
int total = 0;
foreach(Oilfield oilfield in worldmap.Continents[(int)continent].Oilfields) {
if(oilfield.Owner==this && oilfield.Drilled==drilled) {
total+=oilfield.Costs;
}
}
return total;
}
这里是异常的截图:
在这里仔细查看 Locals/Stack-Trace(这是一个旧屏幕截图,但我会在接下来的几个小时内尝试重现此异常,以便展开跟踪):
【问题讨论】:
-
你能提供异常的堆栈跟踪吗?
-
1) 发布内部异常,如果有,或者至少是堆栈跟踪 2) 发布 GetCostCovering() 方法
-
不幸的是没有堆栈跟踪,因为 Visual Studio 只是弹出一个带有上述两行的消息框。 GetCostCovering() 方法紧跟在 ...
-
您是否从另一个线程更改此列表?那么,在排序时,您从另一个线程中删除/添加元素?
-
好的,现在当你点击break时,你可以在
Locals窗口中展开$exception对象。或者,应该显示一个托管调试助手的窗口(假设它已为ArgumentException启用),指向触发异常的行,以便检查堆栈跟踪。