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 =>

Но все равно нет радости.

Итак, что я делаю не так? Заранее спасибо.

1 ответ

Решение

Проходить authorizationRuleCollection.OfType<AuthorizationRule>() в Parallel.ForEach Например:

var typedColletion=authorizationRuleCollection.OfType<AuthorizationRule>();
Parallel.ForEach(typedColletion);

Ошибка вызвана тем, что AuthorizationRuleCollection не реализует IEnumerable<T> но только IEnumerable чьи элементы Object, Это обычный шаблон для более старых (до.NET 2.0) коллекций, когда генерики не были доступны.

Новые классы.NET возвращают / ожидают общие коллекции. По телефону OfType<T>() или же Cast<T>() вы эффективно применяете источник IEnumerable для IEnumerable<T>,

Разница в том, что OfType<T>() будет отфильтровывать несовместимые элементы, в то время как Cast<T>() бросит, если будут найдены какие-либо несовместимые элементы.

Код, стоящий за обоими методами, не магический, в ссылочном источнике это просто итератор над источником 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;
        }
    }
Другие вопросы по тегам