Используя.NET 3.5 С#, у меня есть веб-сервис WCF, обслуживающий мобильные клиенты. Клиенты часто используют службу для отправки данных на сервер и получения обновлений. Служба, развернутая в 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 fine.
// If this class is generated more than once it doesn't matter.
info = new DataClassInfo(type);
classInfos[type] = info;
}
return info;
}
}
Проблема была устранена вручную. Из stacktrace кажется, что статическое поле readInly classInfos может быть NULL, но я не знаю, как это может быть?
Исключение происходит внутри словаря, как вы можете видеть из трассировки стека:
System.Collections.Generic.Dictionary'2.Insert
Практически единственная причина, по которой это может произойти, - это доступ к словарю одновременно. Попробуйте обернуть его внутри оператора lock
.
Я предполагаю, что причина, по которой это происходит во время рециркуляции, приведена ниже. Чтение словаря, вероятно, является потокобезопасным, поэтому шансы на исключение выше во время запуска. И во время повторного использования несколько одновременных клиентских запросов могут приостанавливаться до тех пор, пока приложение не перезагрузится. Поэтому после перезапуска приложения одновременно выполняются несколько попыток записи.
type
может быть нулевым?