private Generic.SortedList <string, string> ReadValues(string p_SubKeyName) { Generic.SortedList <string, string> Retval = new Generic.SortedList <string, string>(); // Read all values in a key - SubKey has to be absolute from the profile store root XmlReaderSettings ReaderSettings; string LastElementName = ""; string NextName = ""; string ValueName = ""; bool ReadOK = false; int RetryCount; bool ErrorOccurred = false; string ValuesFileName; // Name of the profile file from which to read bool ExistsValues, ExistsValuesOriginal, ExistsValuesNew; swSupport.Reset(); swSupport.Start(); // Start timing this call if (Strings.Left(p_SubKeyName, 1) != @"\") { p_SubKeyName = @"\" + p_SubKeyName; // Condition to have leading \ } TL.LogMessage(" ReadValues", " SubKeyName: " + p_SubKeyName); ValuesFileName = VALUES_FILENAME; // Initialise to the file holding current values RetryCount = -1; // Initialise to ensure we get RETRY_Max number of retrys // Determine what files exist and handle the case where this key has not yet been created ExistsValues = FileStore.Exists(p_SubKeyName + @"\" + VALUES_FILENAME); ExistsValuesOriginal = FileStore.Exists(p_SubKeyName + @"\" + VALUES_FILENAME_ORIGINAL); ExistsValuesNew = FileStore.Exists(p_SubKeyName + @"\" + VALUES_FILENAME_NEW); if (!ExistsValues & !ExistsValuesOriginal) { throw new ProfileNotFoundException("No profile files exist for this key: " + p_SubKeyName); } do { RetryCount += 1; try { ReaderSettings = new XmlReaderSettings(); ReaderSettings.IgnoreWhitespace = true; using (XmlReader Reader = XmlReader.Create(FileStore.FullPath(p_SubKeyName + @"\" + ValuesFileName), ReaderSettings)) { Reader.Read(); Reader.Read(); // Start reading profile strings while (Reader.Read()) { switch (Reader.NodeType) { case XmlNodeType.Element: { switch (Reader.Name) { case object _ when DEFAULT_ELEMENT_NAME: { Retval.Add(COLLECTION_DEFAULT_VALUE_NAME, Reader.GetAttribute(VALUE_ATTRIBUTE_NAME)); TL.LogMessage(" ReadValues", " found " + COLLECTION_DEFAULT_VALUE_NAME + " = " + Retval.Item(COLLECTION_DEFAULT_VALUE_NAME)); break; } case object _ when VALUE_ELEMENT_NAME: { ValueName = Reader.GetAttribute(NAME_ATTRIBUTE_NAME); Retval.Add(ValueName, Reader.GetAttribute(VALUE_ATTRIBUTE_NAME)); TL.LogMessage(" ReadValues", " found " + ValueName + " = " + Retval.Item(ValueName)); break; } default: { TL.LogMessage(" ReadValues", " ## Found unexpected Reader.Name: " + Reader.Name.ToString()); break; } } break; } default: { break; } } } Reader.Close(); } swSupport.Stop(); TL.LogMessage(" ReadValues", " added to cache - " + swSupport.ElapsedMilliseconds + " milliseconds"); ReadOK = true; } catch (Exception ex) { ErrorOccurred = true; if (RetryCount == RETRY_MAX) { if (ValuesFileName == VALUES_FILENAME) { ValuesFileName = VALUES_FILENAME_ORIGINAL; RetryCount = -1; LogEvent("XMLAccess:ReadValues", "Error reading profile on final retry - attempting recovery from previous version", EventLogEntryType.Warning, EventLogErrors.XMLAccessRecoveryPreviousVersion, ex.ToString()); TL.LogMessageCrLf(" ReadValues", "Final retry exception - attempting recovery from previous version: " + ex.ToString()); } else { LogEvent("XMLAccess:ReadValues", "Error reading profile on final retry", EventLogEntryType.Error, EventLogErrors.XMLAccessReadError, ex.ToString()); TL.LogMessageCrLf(" ReadValues", "Final retry exception: " + ex.ToString()); throw new ProfilePersistenceException("XMLAccess Exception", ex); } } else { LogEvent("XMLAccess:ReadValues", "Error reading profile - retry: " + RetryCount, EventLogEntryType.Warning, EventLogErrors.XMLAccessRecoveryPreviousVersion, ex.Message); TL.LogMessageCrLf(" ReadValues", "Retry " + RetryCount + " exception: " + ex.ToString()); } } if (ErrorOccurred) { System.Threading.Thread.Sleep(RETRY_INTERVAL); } }while (!ReadOK)// Get rid of the XML version string// Read in the Profile name tag// Found default value// Fount an element name// Close the IO readers// Set the exit flag here when a read has been successful // Wait if an error occurred ; if (ErrorOccurred) { LogEvent("XMLAccess:ReadValues", "Recovered from read error OK", EventLogEntryType.SuccessAudit, EventLogErrors.XMLAccessRecoveredOK, null /* TODO Change to default(_) if this is not a reference type */); TL.LogMessage(" ReadValues", "Recovered from read error OK"); } return(Retval); }