// This function could be re-entrant, so I have kept the flag to make it non-reentrant // I had one call stack in whcih ----eblyLoader.GetTypes() called ServiceProvider.GetService()for which // some one did Marshal.GetObjectForIUnknown() which caused the message pump to be executed // which caused EnsureCurrentTypes to be called once again. private void EnsureCurrentTypes() { if (this.executingEnsureCurrentTypes) { return; } try { bool hasTypeLoadErrors = false; this.executingEnsureCurrentTypes = true; if (this.addedAssemblies != null) { // cache it to local variable string[] addedAssemblies2 = this.addedAssemblies.ToArray(); this.addedAssemblies = null; foreach (string path in addedAssemblies2) { AssemblyLoader loader = null; try { loader = new AssemblyLoader(this, path); this.assemblyLoaders[path] = loader; } catch (Exception e) { this.typeLoadErrors[path] = e; hasTypeLoadErrors = true; } } } if (this.addedCompileUnits != null) { // cache it to local variable CodeCompileUnit[] addedCompileUnits2 = this.addedCompileUnits.ToArray(); this.addedCompileUnits = null; foreach (CodeCompileUnit codeCompileUnit in addedCompileUnits2) { CodeDomLoader loader = null; try { loader = new CodeDomLoader(this, codeCompileUnit); this.compileUnitLoaders[codeCompileUnit] = loader; } catch (Exception e) { // this will cause it to remove types if (loader != null) { loader.Dispose(); } this.typeLoadErrors[codeCompileUnit] = e; hasTypeLoadErrors = true; } } } if (this.needRefreshCompileUnits != null) { // cache it to local variable Dictionary <CodeCompileUnit, EventHandler> needRefreshCompileUnits2 = new Dictionary <CodeCompileUnit, EventHandler>(); foreach (KeyValuePair <CodeCompileUnit, EventHandler> entry in this.needRefreshCompileUnits) { needRefreshCompileUnits2.Add(entry.Key, entry.Value); } this.needRefreshCompileUnits = null; foreach (KeyValuePair <CodeCompileUnit, EventHandler> entry in needRefreshCompileUnits2) { CodeDomLoader codeDomLoader = this.compileUnitLoaders[entry.Key] as CodeDomLoader; Debug.Assert(codeDomLoader != null, "How come we don't have CodeDOMLoader for the guy who needs refresh?"); if (codeDomLoader != null) { try { codeDomLoader.Refresh(entry.Value); } catch (Exception e) { this.typeLoadErrors[entry.Value] = e; hasTypeLoadErrors = true; } } } } if (hasTypeLoadErrors) { if (this.TypeLoadErrorsChanged != null) { FireEventsNoThrow(this.TypeLoadErrorsChanged, new object[] { this, EventArgs.Empty }); } } } finally { this.executingEnsureCurrentTypes = false; } }
private void EnsureCurrentTypes() { if (!this.executingEnsureCurrentTypes) { try { bool flag = false; this.executingEnsureCurrentTypes = true; if (this.addedAssemblies != null) { string[] strArray = this.addedAssemblies.ToArray(); this.addedAssemblies = null; foreach (string str in strArray) { AssemblyLoader loader = null; try { loader = new AssemblyLoader(this, str); this.assemblyLoaders[str] = loader; } catch (Exception exception) { this.typeLoadErrors[str] = exception; flag = true; } } } if (this.addedCompileUnits != null) { CodeCompileUnit[] unitArray = this.addedCompileUnits.ToArray(); this.addedCompileUnits = null; foreach (CodeCompileUnit unit in unitArray) { CodeDomLoader loader2 = null; try { loader2 = new CodeDomLoader(this, unit); this.compileUnitLoaders[unit] = loader2; } catch (Exception exception2) { if (loader2 != null) { loader2.Dispose(); } this.typeLoadErrors[unit] = exception2; flag = true; } } } if (this.needRefreshCompileUnits != null) { Dictionary <CodeCompileUnit, EventHandler> dictionary = new Dictionary <CodeCompileUnit, EventHandler>(); foreach (KeyValuePair <CodeCompileUnit, EventHandler> pair in this.needRefreshCompileUnits) { dictionary.Add(pair.Key, pair.Value); } this.needRefreshCompileUnits = null; foreach (KeyValuePair <CodeCompileUnit, EventHandler> pair2 in dictionary) { CodeDomLoader loader3 = this.compileUnitLoaders[pair2.Key] as CodeDomLoader; if (loader3 != null) { try { loader3.Refresh(pair2.Value); } catch (Exception exception3) { this.typeLoadErrors[pair2.Value] = exception3; flag = true; } } } } if (flag && (this.TypeLoadErrorsChanged != null)) { FireEventsNoThrow(this.TypeLoadErrorsChanged, new object[] { this, EventArgs.Empty }); } } finally { this.executingEnsureCurrentTypes = false; } } }