IIS循环事件后的.NET类型初始化异常

时间:2014-12-02 14:14:12

标签: c# .net wcf iis-7.5 application-pool

使用.NET 3.5 C#,我有一个为移动客户端提供服务的WCF Web服务。客户端经常使用该服务将数据发送到服务器并接收更新。该服务部署在IIS 7.5中,并配置为每天早上06:00回收。回收通常无缝地工作,客户继续像往常一样使用该服务。然而,有几个事件,循环导致应用程序进入一个有趣的状态,我可以看到日志充满类型初始化错误如下。这几乎就像在重叠的重新拼接期间发生的事情,它没有成功地卸载DLL:

System.NullReferenceException: 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.set_Item(TKey key, TValue value)
   at Docobo.Keswick.DbAccess.TableData.DataClasses.GetInfo(Type type)

DataClasses是IQToolkit用于查找数据库表名的内部静态类:

internal static class DataClasses
{
    private static readonly Dictionary<Type, DataClassInfo> classInfos = new Dictionary<Type, DataClassInfo>();

    public static DataClassInfo GetInfo(Type type)
    {
        DataClassInfo info;
        if (!classInfos.TryGetValue(type, out info))
        {
            // This is not thread-safe, but that's fine.
            // If this class is generated more than once it doesn't matter.
            info = new DataClassInfo(type);
            classInfos[type] = info;
        }
        return info;
    }
}

手动回收应用程序池解决了问题。 从堆栈跟踪看来,静态只读字段 classInfos 可能是NULL但我不知道它是怎么回事?

1 个答案:

答案 0 :(得分:4)

异常发生在字典中,正如您可以从堆栈跟踪中看到的那样:

System.Collections.Generic.Dictionary`2.Insert

它可能发生的唯一原因是同时访问字典。尝试将其包装在lock语句中。

我猜测它在循环过程中发生的原因如下。读字典可能是线程安全的,因此在启动期间异常的可能性更高。在回收期间,可能会暂停多个同时发生的客户端请求,等待应用程序重新启动。因此,在应用程序重新启动后,会同时发生多次写入尝试。