我具有以下属性:
private static Collection<Assembly> _loadedAssemblies = new Collection<Assembly>();
internal static ReadOnlyCollection<Assembly> LoadedAssemblies
{
get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies); }
}
在另一个类中,我遍历
LoadedAssemblies
foreach (Assembly assembly in ResourceLoader.LoadedAssemblies)
在遍历程序集时,基础集合(
_loadedAssemblies
)有时会更改,从而给出System.InvalidOperationException
。使LoadedAssemblies
安全的首选方法是什么?我无法重现该问题,所以我不能只是尝试一下。可以吗?
internal static ReadOnlyCollection<Assembly> LoadedAssemblies
{
get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies.ToList()); }
}
编辑
public static void Initialize()
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
AddAssembly(assembly);
}
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyLoad += OnAssemblyLoad;
}
private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
AddAssembly(args.LoadedAssembly);
}
private static void AddAssembly(Assembly assembly)
{
AssemblyName assemblyName = new AssemblyName(assembly.FullName);
string moduleName = assemblyName.Name;
if (!_doesNotEndWith.Exists(x => moduleName.EndsWith(x, StringComparison.OrdinalIgnoreCase)) &&
_startsWith.Exists(x => moduleName.StartsWith(x, StringComparison.OrdinalIgnoreCase)))
{
if (!_loadedAssemblies.Contains(assembly))
{
_loadedAssemblies.Add(assembly);
}
}
}
最佳答案
您的问题中的建议将起作用。那是:
internal static ReadOnlyCollection<Assembly> LoadedAssemblies
{
get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies.ToList()); }
}
原因是您的问题来自
_loadedAssemblies
进行枚举时被更改。当然会发生这种情况,因为ReadOnlyCollection
只是_loadedAssemblies
的包装,该包装使用基集合的枚举器。如果您执行
_loadedAssemblies.ToList()
,则这将创建一个新列表,该列表是原始_loadedAssemblies
的副本。它在创建时将具有所有相同的元素,但将永远不会再次更新(因为您甚至没有对新集合的引用,因此无法对其进行修改)。这意味着,当更新_loadedAssemblies
时,ReadOnlyCollection
中的新列表将非常高兴地不知道该更改,因此您的枚举将毫无问题地继续进行到最后。关于c# - 迭代时修改了Collection的ReadOnlyCollection属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45688470/