Parallel.ForEach 通过 AuthorizationRuleCollection
Parallel.ForEach over AuthorizationRuleCollection
希望有人能指出我在这里做错了什么。我有一个读取文件访问规则的进程,我正在尝试 运行 并行处理它。
这是我目前的代码:
public List<FolderAccessRule> GetSecurityGroupsForFolder(long importId, string subdirectory, bool includeInherited)
{
ConcurrentQueue<FolderAccessRule> groups = new ConcurrentQueue<FolderAccessRule>();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
DirectoryInfo dInfo = new DirectoryInfo(subdirectory);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
AuthorizationRuleCollection authorizationRuleCollection = dSecurity.GetAccessRules(true, includeInherited, typeof(NTAccount));
Parallel.ForEach( authorizationRuleCollection,
fsar =>
{
try
{
FolderAccessRule group = this.GetGroup(fsar);
if (group != null)
{
groups.Enqueue(group);
}
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
foreach (Exception e in exceptions)
{
string message = string.Concat(e.GetType(), "Exception getting Directory info for ", subdirectory);
this.RecordException(message, subdirectory, e);
}
return groups.ToList();
}
这(对于未经训练的人来说)看起来应该有效。但是 Parallel.ForEach
不会编译,因为它会给出错误:
The type arguments for method 'System.Threading.Tasks.Parallel.ForEach<TSource>
(System.Collections.Generic.IEnumerable<TSource>, System.Action<TSource>)' cannot be inferred from the usage.
Try specifying the type arguments explicitly.
我也试过将违规行更改为:
Parallel.ForEach<FileSystemAccessRule>( authorizationRuleCollection, fsar =>
但还是不开心
那么,我做错了什么?
提前致谢。
将authorizationRuleCollection.OfType<AuthorizationRule>()
传递给Parallel.ForEach
,例如:
var typedColletion=authorizationRuleCollection.OfType<AuthorizationRule>();
Parallel.ForEach(typedColletion);
错误是因为AuthorizationRuleCollection
doesn't implement IEnumerable<T>
but only IEnumerable
,其元素是Object
。当泛型不可用时,这是较旧(.NET 2.0 之前)集合的常见模式。
较新的 .NET 类 return/expect 通用集合。通过调用 OfType<T>()
or Cast<T>()
,您可以有效地将源 IEnumerable
转换为 IEnumerable<T>
.
区别在于OfType<T>()
will filter out incompatible elements, while Cast<T>()
如果发现任何不兼容的元素将抛出。
这两种方法背后的 code 并不神奇,在参考源中它只是对源 IEnumerable
:
的迭代器
public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
if (source == null) throw Error.ArgumentNull("source");
return OfTypeIterator<TResult>(source);
}
static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
foreach (object obj in source) {
if (obj is TResult) yield return (TResult)obj;
}
}
希望有人能指出我在这里做错了什么。我有一个读取文件访问规则的进程,我正在尝试 运行 并行处理它。
这是我目前的代码:
public List<FolderAccessRule> GetSecurityGroupsForFolder(long importId, string subdirectory, bool includeInherited)
{
ConcurrentQueue<FolderAccessRule> groups = new ConcurrentQueue<FolderAccessRule>();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
DirectoryInfo dInfo = new DirectoryInfo(subdirectory);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
AuthorizationRuleCollection authorizationRuleCollection = dSecurity.GetAccessRules(true, includeInherited, typeof(NTAccount));
Parallel.ForEach( authorizationRuleCollection,
fsar =>
{
try
{
FolderAccessRule group = this.GetGroup(fsar);
if (group != null)
{
groups.Enqueue(group);
}
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
foreach (Exception e in exceptions)
{
string message = string.Concat(e.GetType(), "Exception getting Directory info for ", subdirectory);
this.RecordException(message, subdirectory, e);
}
return groups.ToList();
}
这(对于未经训练的人来说)看起来应该有效。但是 Parallel.ForEach
不会编译,因为它会给出错误:
The type arguments for method 'System.Threading.Tasks.Parallel.ForEach<TSource>
(System.Collections.Generic.IEnumerable<TSource>, System.Action<TSource>)' cannot be inferred from the usage.
Try specifying the type arguments explicitly.
我也试过将违规行更改为:
Parallel.ForEach<FileSystemAccessRule>( authorizationRuleCollection, fsar =>
但还是不开心
那么,我做错了什么? 提前致谢。
将authorizationRuleCollection.OfType<AuthorizationRule>()
传递给Parallel.ForEach
,例如:
var typedColletion=authorizationRuleCollection.OfType<AuthorizationRule>();
Parallel.ForEach(typedColletion);
错误是因为AuthorizationRuleCollection
doesn't implement IEnumerable<T>
but only IEnumerable
,其元素是Object
。当泛型不可用时,这是较旧(.NET 2.0 之前)集合的常见模式。
较新的 .NET 类 return/expect 通用集合。通过调用 OfType<T>()
or Cast<T>()
,您可以有效地将源 IEnumerable
转换为 IEnumerable<T>
.
区别在于OfType<T>()
will filter out incompatible elements, while Cast<T>()
如果发现任何不兼容的元素将抛出。
这两种方法背后的 code 并不神奇,在参考源中它只是对源 IEnumerable
:
public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
if (source == null) throw Error.ArgumentNull("source");
return OfTypeIterator<TResult>(source);
}
static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
foreach (object obj in source) {
if (obj is TResult) yield return (TResult)obj;
}
}