C# I';m getting`System.InvalidOperationException:集合已修改;枚举操作可能无法执行“”,令人费解
我得到C# I';m getting`System.InvalidOperationException:集合已修改;枚举操作可能无法执行“”,令人费解,c#,.net,ienumerable,C#,.net,Ienumerable,我得到System.invalidoOperationException:集合被修改;枚举操作不能执行: ExceptionLoggingLibrary.LoggingException: Exception of type 'ExceptionLoggingLibrary.LoggingException' was thrown. ---> System.InvalidOperationException: Collection was modified; enumeration ope
System.invalidoOperationException:集合被修改;枚举操作不能执行
:
ExceptionLoggingLibrary.LoggingException: Exception of type 'ExceptionLoggingLibrary.LoggingException' was thrown. ---> System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at iTextSharp.text.FontFactoryImp.GetFont(String fontname, String encoding, Boolean embedded, Single size, Int32 style, BaseColor color, Boolean cached)
[...]
据我所知,当IEnumerable对象在枚举过程中被修改时,就会发生这种异常
下面是iTextSharp.text.FontFactoryImp.GetFont
方法:
public virtual Font GetFont(string fontname, string encoding, bool embedded, float size, int style, BaseColor color, bool cached) {
if (fontname == null) return new Font(Font.FontFamily.UNDEFINED, size, style, color);
string lowercasefontname = fontname.ToLower(CultureInfo.InvariantCulture);
List<string> tmp;
fontFamilies.TryGetValue(lowercasefontname, out tmp);
if (tmp != null) {
// some bugs were fixed here by Daniel Marczisovszky
int fs = Font.NORMAL;
bool found = false;
int s = style == Font.UNDEFINED ? Font.NORMAL : style;
foreach (string f in tmp) {
string lcf = f.ToLower(CultureInfo.InvariantCulture);
fs = Font.NORMAL;
if (lcf.ToLower(CultureInfo.InvariantCulture).IndexOf("bold") != -1) fs |= Font.BOLD;
if (lcf.ToLower(CultureInfo.InvariantCulture).IndexOf("italic") != -1 || lcf.ToLower(CultureInfo.InvariantCulture).IndexOf("oblique") != -1) fs |= Font.ITALIC;
if ((s & Font.BOLDITALIC) == fs) {
fontname = f;
found = true;
break;
}
}
if (style != Font.UNDEFINED && found) {
style &= ~fs;
}
}
BaseFont basefont = null;
try {
try {
// the font is a type 1 font or CJK font
basefont = BaseFont.CreateFont(fontname, encoding, embedded, cached, null, null, true);
}
catch (DocumentException) {
}
if (basefont == null) {
// the font is a true type font or an unknown font
trueTypeFonts.TryGetValue(fontname.ToLower(CultureInfo.InvariantCulture), out fontname);
// the font is not registered as truetype font
if (fontname == null) return new Font(Font.FontFamily.UNDEFINED, size, style, color);
// the font is registered as truetype font
basefont = BaseFont.CreateFont(fontname, encoding, embedded, cached, null, null);
}
}
catch (DocumentException de) {
// this shouldn't happen
throw de;
}
catch (System.IO.IOException) {
// the font is registered as a true type font, but the path was wrong
return new Font(Font.FontFamily.UNDEFINED, size, style, color);
}
catch {
// null was entered as fontname and/or encoding
return new Font(Font.FontFamily.UNDEFINED, size, style, color);
}
return new Font(basefont, size, style, color);
}
公共虚拟字体GetFont(字符串fontname、字符串编码、布尔嵌入、浮点大小、int样式、基色颜色、布尔缓存){
如果(fontname==null)返回新字体(Font.FontFamily.UNDEFINED、大小、样式、颜色);
字符串lowercasefontname=fontname.ToLower(CultureInfo.InvariantCulture);
列出tmp;
TryGetValue(小写的字体名称,输出tmp);
如果(tmp!=null){
//Daniel Marczisovszky在这里修复了一些bug
int fs=Font.NORMAL;
bool-found=false;
int s=style==Font.UNDEFINED?Font.NORMAL:style;
foreach(tmp中的字符串f){
字符串lcf=f.ToLower(CultureInfo.InvariantCulture);
fs=Font.NORMAL;
if(lcf.ToLower(CultureInfo.InvariantCulture).IndexOf(“粗体”)!=-1)fs |=Font.bold;
if(lcf.ToLower(CultureInfo.InvariantCulture).IndexOf(“italic”)!=-1 | | lcf.ToLower(CultureInfo.InvariantCulture).IndexOf(“italic”)!=-1)fs |=Font.italic;
如果((s&Font.BOLDITALIC)==fs){
fontname=f;
发现=真;
打破
}
}
if(style!=Font.UNDEFINED&&found){
风格&=~fs;
}
}
BaseFont BaseFont=null;
试一试{
试一试{
//字体为1型字体或CJK字体
basefont=basefont.CreateFont(fontname、编码、嵌入、缓存、null、null、true);
}
捕获(文档异常){
}
if(basefont==null){
//该字体是真字型字体或未知字体
trueTypeFonts.TryGetValue(fontname.ToLower(CultureInfo.InvariantCulture),out fontname);
//该字体未注册为truetype字体
如果(fontname==null)返回新字体(Font.FontFamily.UNDEFINED、大小、样式、颜色);
//该字体已注册为truetype字体
basefont=basefont.CreateFont(fontname、编码、嵌入、缓存、null、null);
}
}
catch(DocumentException de){
//这不应该发生
丢德;
}
捕获(System.IO.IOException){
//该字体已注册为true type字体,但路径错误
返回新字体(Font.FontFamily.UNDEFINED、大小、样式、颜色);
}
抓住{
//输入null作为fontname和/或编码
返回新字体(Font.FontFamily.UNDEFINED、大小、样式、颜色);
}
返回新字体(基本字体、大小、样式、颜色);
}
在该方法中,有可能在枚举过程中修改IEnumerable对象吗?在不知道方法内部内容的情况下,这将防止在枚举过程中更改集合: 更改:
List<string> tmp;
fontFamilies.TryGetValue(lowercasefontname, out tmp);
列出tmp;
TryGetValue(小写的字体名称,输出tmp);
致:
列表共享列表;
TryGetValue(小写的FontName,out-sharedList);
var tmp=新列表(共享列表);
这将为您提供一个新列表,您可以确保任何其他线程都不会访问该列表,因为它保证不仅仅是TryGetValue()中列表的引用
我已从以前更改了tmp列表的名称,并将新列表命名为tmp,这样您就不需要更改任何其他代码。在运行此代码时,另一个线程似乎正在修改集合,因为此方法根本不修改集合。您的问题在代码的其他地方。如果正在修改的集合是tmp,为什么不在列表返回时对其进行深度复制,以便您不必担心它在其他地方被修改?@CLandry,不确定,它不是我的库。我只是想弄清它的底细。引发此异常是因为其他代码在另一时间修改了集合。当GetFont()到达时,损坏已经造成。是的,很难调试,它需要一个带水晶球的时间机器。
List<string> sharedList;
fontFamilies.TryGetValue(lowercasefontname, out sharedList);
var tmp = new List<string>(sharedList);