当ArgumentNullException缺少参数名称时

时间:2013-09-20 10:02:05

标签: c# .net visual-studio-2010

在我的应用程序中,几次ArgumentNullException被抛出,但没有提供任何参数名称。这只发生在生产中(异常是在脚本服务中引发的,由javascript调用)。 我试图在StackTrace指向的代码片段中重现这种错误,但我能够重现的每个ArgumentNullException在其消息中都包含一些参数名称。

所以,我的问题是,有人知道在没有提供参数名称的情况下抛出ArgumentNullException的时间吗?或者什么方法最终会触发这个例外?



脚本服务是从应用程序缓存中获取一些信息:

private Dictionary<int, MyType> CachedDictionary
{
    get
    {
        //return the Item from the application cache
        return GetItem() as Dictionary<int, MyType>;
    }
    set
    {
        //adds the Item to the application cache 
        //with sliding expiration of X minutes
        AddItem(value);
    }
}

public List<MyType> Get(List<int> idsToRead)
{
    List<int> idsNotCached = idsToRead.Except<int>(CachedDictionary.Keys.ToList<int>()).ToList<int>();
    if (idsNotCached.Count > 0)
    {
        //Exception stack trace points to next line:
        MyTypeCollection DBitems = BusinessLayer.StaticLoadFromDB(idsNotCached); 
        lock (CachedDictionary)
        {
            foreach (MyType item in DBitems)
                if (!CachedDictionary.ContainsKey(item.ID))
                    CachedDictionary.Add(item.ID, item);
        }
    }
    return CachedDictionary.Where(p => idsToRead.Contains(p.Key)).Select(p => p.Value).ToList<MyType>();
}


public static MyTypeCollection StaticLoadFromDB(List<int> ids)
{
    try
    {
        //load from db...
    }
    catch (Exception e)
    {
        return HandleException<MyType>(e);
        //returns MyTypeCollection with HasError set to TRUE and defined ErrorMessage
    }
}

4 个答案:

答案 0 :(得分:2)

没有代码,很难确定可能的原因。您可以尝试以下一般准则来尝试识别问题。

当未提供方法的参数时,通常会触发异常ArgumentNullExceptionArgumentNullException的构造函数不需要提供参数名称。有些方法只接受一个参数,因此不需要提供null参数的名称。

只需

即可在代码中的任何位置触发异常
throw new ArgumentNullException();

为了帮助确定问题的原因,您需要查看堆栈跟踪,然后查看提供的参数。尝试确定当时正在尝试执行的操作,从而确定可能的参数值。

或者,您可以尝试添加try catch,以记录调用时发送给方法的可能值。例如,

try
{
    FunctionThatThrowsArgumentNullException(myParameter);
} catch (ArgumentNullException ane)
{
    Log.WriteLine("Argument Null Exception Raised", ane);
    Log.WriteLine("Parameters supplied : {0}", myParameter);
    throw; // Pass the exception on, as we are only logging
}

答案 1 :(得分:2)

ArgumentNullException是公共的,任何人都可以抛出此异常。您的同事或您使用的第三方图书馆可能会抛出它。

您必须通过查看异常中的堆栈跟踪来回答您自己的问题。这将告诉您抛出异常的位置,以及它之前的所有方法。

以此代码为例: enter image description here

通过检查异常,您可以看到错误的来源。在堆栈顶部跟踪是抛出异常的方法,然后是导致它的方法调用链。 enter image description here

答案 2 :(得分:0)

如前所述,您没有使用任何第三方库,可能会在您自己的代码库中抛出异常。正如Kami解释的那样,引发此异常的代码可以标识为:

throw new ArgumentNullException();

为什么不在代码库中搜索此行?如果幸运的话,你会发现引发这个异常的地方而不传递参数名称!

答案 3 :(得分:0)

伙计们,非常感谢你们的关注 正如Kami建议的那样,我添加了一些额外的记录,幸运的是,异常被复制了,现在一切都很清楚了 似乎在这一行之后:

List<int> idsNotCached = idsToRead.Except<int>(CachedDictionary.Keys.ToList<int>()).ToList<int>();

(参见上面提供的代码示例)CachedDictionary已过期且在线:

lock (CachedDictionary)

抛出ArgumentNullException而不提供参数名称。显然我错过了测试这个锁。 通过一些额外的代码行解决问题:

public List<MyType> Get(List<int> idsToRead)
{
    Dictionary<int, MyType> localCachedDictionary = CachedDictionary;
    if (localCachedDictionary == null)
        localCachedDictionary = new Dictionar<int, MyType>();
    List<int> idsNotCached = idsToRead.Except<int>(localCachedDictionary.Keys.ToList<int>()).ToList<int>();
    if (idsNotCached.Count > 0)
    {
        //Exception stack trace points to next line:
        MyTypeCollection DBitems = BusinessLayer.StaticLoadFromDB(idsNotCached); 
        lock (localCachedDictionary)
        {
            foreach (MyType item in DBitems)
                if (!localCachedDictionary.ContainsKey(item.ID))
                    localCachedDictionary.Add(item.ID, item);
        }
    }
    if (CachedDictionary == null)
        CachedDictionary = localCachedDictionary;
    return localCachedDictionary.Where(p => idsToRead.Contains(p.Key)).Select(p => p.Value).ToList<MyType>();
}