private static void RemoveSpecificCustomCharacterSetting(string strSettingName) { if (_intDicLoadedCharacterSettingsLoadedStatus <= 1) { return; } CharacterSettings objSettingsToDelete = s_DicLoadedCharacterSettings.FirstOrDefault(x => x.Value.FileName == strSettingName).Value; if (objSettingsToDelete == default) { return; } try { Lazy <string> strBestMatchNewSettingsKey = new Lazy <string>(() => { int intBestScore = int.MinValue; string strReturn = string.Empty; foreach (CharacterSettings objExistingSettings in s_DicLoadedCharacterSettings.Values) { // ReSharper disable once AccessToDisposedClosure if (objSettingsToDelete.DictionaryKey == objExistingSettings.DictionaryKey) { continue; } // ReSharper disable once AccessToDisposedClosure int intLoopScore = CalculateCharacterSettingsMatchScore(objSettingsToDelete, objExistingSettings); if (intLoopScore > intBestScore) { intBestScore = intLoopScore; strReturn = objExistingSettings.DictionaryKey; } } return(strReturn); }); foreach (Character objCharacter in Program.OpenCharacters) { if (objCharacter.SettingsKey == objSettingsToDelete.DictionaryKey) { objCharacter.SettingsKey = strBestMatchNewSettingsKey.Value; } } } finally { s_DicLoadedCharacterSettings.Remove(objSettingsToDelete.DictionaryKey); objSettingsToDelete.Dispose(); } }
/// <summary> /// Get the compiled Xsl Transform of an Xsl file. Will throw exceptions if anything goes awry. /// If we've already compiled the same Xsl Transform before, we'll fetch the cached version of that transform instead of repeating it. /// </summary> /// <param name="strXslFilePath">Absolute path to the Xsl file to be transformed.</param> /// <returns>The compiled Xsl transform of <paramref name="strXslFilePath"/>.</returns> public static XslCompiledTransform GetTransformForFile(string strXslFilePath) { if (!File.Exists(strXslFilePath)) { throw new FileNotFoundException(nameof(strXslFilePath)); } DateTime datLastWriteTimeUtc = File.GetLastWriteTimeUtc(strXslFilePath); XslCompiledTransform objReturn; if (!s_dicCompiledTransforms.TryGetValue( strXslFilePath, out Tuple <DateTime, XslCompiledTransform> tupCachedData) || tupCachedData.Item1 <= datLastWriteTimeUtc) { #if DEBUG objReturn = new XslCompiledTransform(true); #else objReturn = new XslCompiledTransform(); #endif objReturn.Load(strXslFilePath); s_dicCompiledTransforms.Remove(strXslFilePath); s_dicCompiledTransforms.TryAdd( strXslFilePath, new Tuple <DateTime, XslCompiledTransform>(datLastWriteTimeUtc, objReturn)); } else { objReturn = tupCachedData.Item2; } return(objReturn); }
/// <summary> /// Get the compiled Xsl Transform of an Xsl file. Will throw exceptions if anything goes awry. /// If we've already compiled the same Xsl Transform before, we'll fetch the cached version of that transform instead of repeating it. /// Uses flag hack method design outlined here to avoid locking: /// https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development /// </summary> /// <param name="blnSync">Flag for whether method should always use synchronous code or not.</param> /// <param name="strXslFilePath">Absolute path to the Xsl file to be transformed.</param> /// <returns>The compiled Xsl transform of <paramref name="strXslFilePath"/>.</returns> private static async Task <XslCompiledTransform> GetTransformForFileCoreAsync(bool blnSync, string strXslFilePath) { if (!File.Exists(strXslFilePath)) { throw new FileNotFoundException(nameof(strXslFilePath)); } DateTime datLastWriteTimeUtc = File.GetLastWriteTimeUtc(strXslFilePath); XslCompiledTransform objReturn; bool blnSuccess; Tuple <DateTime, XslCompiledTransform> tupCachedData; if (blnSync) { // ReSharper disable once MethodHasAsyncOverload blnSuccess = s_dicCompiledTransforms.TryGetValue(strXslFilePath, out tupCachedData); } else { (blnSuccess, tupCachedData) = await s_dicCompiledTransforms.TryGetValueAsync(strXslFilePath); } if (!blnSuccess || tupCachedData.Item1 <= datLastWriteTimeUtc) { #if DEBUG objReturn = new XslCompiledTransform(true); #else objReturn = new XslCompiledTransform(); #endif if (blnSync) { objReturn.Load(strXslFilePath); // ReSharper disable once MethodHasAsyncOverload s_dicCompiledTransforms.Remove(strXslFilePath); // ReSharper disable once MethodHasAsyncOverload s_dicCompiledTransforms.TryAdd( strXslFilePath, new Tuple <DateTime, XslCompiledTransform>(datLastWriteTimeUtc, objReturn)); } else { await Task.Run(() => objReturn.Load(strXslFilePath)); await s_dicCompiledTransforms.RemoveAsync(strXslFilePath); await s_dicCompiledTransforms.TryAddAsync( strXslFilePath, new Tuple <DateTime, XslCompiledTransform>(datLastWriteTimeUtc, objReturn)); } } else { objReturn = tupCachedData.Item2; } return(objReturn); }
public async ValueTask GeneratePersistentsAsync(CultureInfo objCulture, string strLanguage) { List <string> lstPersistentKeysToRemove = new List <string>(_dicPersistentModules.Count); foreach (KeyValuePair <string, StoryModule> objPersistentModule in _dicPersistentModules) { if (objPersistentModule.Value.IsRandomlyGenerated) { lstPersistentKeysToRemove.Add(objPersistentModule.Key); } } foreach (string strKey in lstPersistentKeysToRemove) { _dicPersistentModules.Remove(strKey); } foreach (StoryModule objModule in Modules) { await objModule.TestRunToGeneratePersistents(objCulture, strLanguage); } _blnNeedToRegeneratePersistents = false; }
public void Dispose() { if (_blnDisposed) { return; } _blnDisposed = true; if (_objControl == null) { lock (s_ObjApplicationWaitCursorsLock) { --_intApplicationWaitCursors; if (_intApplicationWaitCursors <= 0) { Application.UseWaitCursor = false; } } return; } Log.Trace("CursorWait for Control \"" + _objControl + "\" disposing with Guid \"" + _guidInstance + "\" after " + _objTimer.ElapsedMilliseconds + "ms."); _objTimer.Stop(); if (!s_DicWaitingControls.TryGetValue(_objControl, out ThreadSafeList <CursorWait> lstCursorWaits) || lstCursorWaits == null || lstCursorWaits.Count == 0) { Utils.BreakIfDebug(); Log.Error("CursorWait for Control \"" + _objControl + "\" with Guid \"" + _guidInstance + "\" somehow does not have a CursorWait list defined for it"); throw new InvalidOperationException(nameof(lstCursorWaits)); } int intMyIndex = lstCursorWaits.FindLastIndex(x => x.Equals(this)); if (intMyIndex < 0 || !lstCursorWaits.Remove(this)) { Utils.BreakIfDebug(); Log.Error("CursorWait for Control \"" + _objControl + "\" with Guid \"" + _guidInstance + "\" somehow is not in the CursorWait list defined for it"); throw new InvalidOperationException(nameof(intMyIndex)); } if (intMyIndex >= lstCursorWaits.Count) { CursorWait objPreviousCursorWait = null; // Need this pattern because the size of lstExisting might change in between fetching lstExisting.Count and lstExisting[] bool blnDoLoop = true; while (blnDoLoop) { blnDoLoop = false; int intIndex = lstCursorWaits.Count - 1; if (intIndex >= 0) { try { objPreviousCursorWait = lstCursorWaits[intIndex]; } catch (ArgumentOutOfRangeException) { blnDoLoop = true; } } } SetControlCursor(objPreviousCursorWait?.CursorToUse); } if (lstCursorWaits.Count != 0) { return; } s_DicWaitingControls.Remove(_objControl); lstCursorWaits.Dispose(); }