什么会导致该属性偶尔抛出一个NullReferenceException? [英] What would cause this property to occasionally throw a NullReferenceException?
问题描述
我有一个asp.net/C#类,调整大小的图像对服务器上的文件缓存中,code,决定带codeR用这似乎偶尔抛出一个NullReferenceException的不过部分。
I have an asp.net/C# class that resizes images for caching on the server as files, however the portion of the code that determines which encoder to use seems to occasionally throw a NullReferenceException.
下面是code这初始化并传回恩codeRS:
Here is the code which initializes and passes back the encoders:
public static class ImageUtilities{
private static Dictionary<string, ImageCodecInfo> encoders = null;
public static Dictionary<string, ImageCodecInfo> Encoders{
get{
if (encoders == null){
encoders = new Dictionary<string, ImageCodecInfo>();
}
//if there are no codecs, try loading them
if (encoders.Count == 0){
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders()){
encoders.Add(codec.MimeType.ToLower(), codec);
}
}
return encoders;
}
}
...
这是异常被抛出对具体的线路:
This is the specific line the exception is being thrown on:
encoders.Add(codec.MimeType.ToLower(), codec);
这是错误文本:
Object reference not set to an instance of an object.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
这是只有在恩codeRS属性被称为地方(随后是低于一个在堆栈跟踪行):
This is the only place where the Encoders property is called (and subsequently is the line below that one in the stack trace):
if (Encoders.ContainsKey(lookupKey)){
foundCodec = Encoders[lookupKey];
}
即使lookupKey都为空的,不应该查找刚刚返回null而不是抛出一个异常?
Even if lookupKey were null, shouldn't the lookup just return null rather than throwing an exception?
推荐答案
您正在尝试使用懒加载单,但你不考虑并发性考虑。要做到这一点不牺牲性能的最简单的方法是用懒&LT; T&GT;
:
You're attempting to use a "lazy loaded singleton", but you're not taking concurrency into account. The easiest way to do this without sacrificing performance is with Lazy<T>
:
private static Lazy<Dictionary<string, ImageCodecInfo>> _encoders =
new Lazy<Dictionary<string, ImageCodecInfo>>(() =>
ImageCodecInfo.GetImageEncoders().ToDictionary(x => x.MimeType.ToLower(), x => x));
public static Dictionary<string, ImageCodecInfo> Encoders
{
get { return _encoders.Value; }
}
这是乔恩斯基特对各种方式优秀文章的格局#6你可以实现这种模式
您也可以考虑使用一个只读的字典,以prevent任何主叫方试图添加到它。
You might also consider using a read-only dictionary, to prevent any callers from trying to add to it.
private static Lazy<ReadOnlyDictionary<string, ImageCodecInfo>> _encoders =
new Lazy<ReadOnlyDictionary<string, ImageCodecInfo>>(() =>
new ReadOnlyDictionary<string, ImageCodecInfo>(
ImageCodecInfo.GetImageEncoders()
.ToDictionary(x => x.MimeType.ToLower(), x => x)));
public static IReadOnlyDictionary<string, ImageCodecInfo> Encoders
{
get { return _encoders.Value; }
}
您可能会处理这另一种方法是用 ConcurrentDictionary
,但似乎有点小题大做,因为你不打算要经常添加物品。
Another way you might handle this is with a ConcurrentDictionary
, but that seems like overkill since you're not going to be adding items frequently.
这篇关于什么会导致该属性偶尔抛出一个NullReferenceException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!