什么会导致该属性偶尔抛出一个NullReferenceException? [英] What would cause this property to occasionally throw a NullReferenceException?

查看:186
本文介绍了什么会导致该属性偶尔抛出一个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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆