Task.run параллельно для C#

в настоящее время у меня есть следующий цикл foreach

foreach (var formId in formIdList)
        {
            var hasAccess = Task.Run(async () => await _userAccessService.HasAccessToFormId(formId)).Result;
            if (!hasAccess)
            {
                throw new UnauthorizedAccessException();
            }
        }

пытаясь выяснить, как сделать больше задачи. когда все виды конструкции, чтобы все функции могли работать параллельно, и если какой-либо из них возвращает false для var hasaccess, то генерирует несанкционированное исключение.

/ ************************* обновленный вопрос для токена отмены ************

используя решение jstewards ниже. немного не уверен, как использовать токен отмены (прошу прощения, я больше являюсь разработчиком интерфейса, поэтому здесь я немного не в своем элементе)

как использовать токен для отмены запущенных задач?

public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        var formIdList = AttributeRequestHelper.GetFormIdList(filterContext.ActionArguments);

        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;

        Task.Run(async () => await CheckIds(formIdList),token);

    }

    public async Task CheckIds(IEnumerable<int> formIdList)
    {
        var results = formIdList.Select(id => _userAccessService.HasAccessToFormId(id)).ToList();
        while (results.Any())
        {
            var result = await Task.WhenAny(results);
            results.Remove(result);
            var authorized = await result;
            if (!authorized) throw new UnauthorizedAccessException();
        }
    }

Вы бы предпочли вариант с «коротким замыканием», когда произойдет первый отказ? Или вы хотите подождать, пока все не закончатся, прежде чем выбросить исключение?

Dan Rayson 20.09.2018 17:34

да короткое замыкание было бы даже лучше

Bryan Dellinger 20.09.2018 17:35

@RossBush Почему именно WithDegreeOfParallelism (6)? Как правило, нет необходимости указывать количество используемых потоков, поскольку TPL определит наилучшее количество необходимых потоков.

ckuri 20.09.2018 17:38

@ckuri - Вы правы, однако есть несколько крайних случаев, особенно при смешивании длинных вызовов доступа к базе данных, которые могут заставить TPL думать, что выполняется меньше работы, и объединять больше потоков, чем идеально.

Ross Bush 20.09.2018 17:47

Вы можете немного сократить это как formIdList.AsParallel (). ForAll (formId => {}

Ross Bush 20.09.2018 17:53

@ckuri Я удалил свой предыдущий комментарий и добавил один, удаляющий WithDegreeOfParallelism, так как это может вызвать путаницу.

Ross Bush 20.09.2018 17:54

Рассматривали ли вы возможность передать массив в HasAccessToFormId и позволить вашей базе данных делать тяжелую работу вместо того, чтобы забивать ее отдельными запросами?

nvoigt 20.09.2018 18:40

@RossBush Разве PLINQ ForAll не выполняет только действия, а не Func<Task<bool>>?

JSteward 20.09.2018 18:51

@JSteward - Да, и если вам нужно полностью выйти из строя, исключение остановит только последующие спауны, вам все равно понадобится схема отмены / обратного вызова, чтобы остановить уже запущенные потоки. Я неправильно истолковал вопрос.

Ross Bush 20.09.2018 19:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
131
1

Ответы 1

Как насчет этого, он бросит на первый неавторизованный идентификатор. Однако здесь нет возможности отменить другой запрос, поэтому они просто игнорируются. Я бы посоветовал поработать в CancellationToken, чтобы отменить другие задачи, поскольку вас не волнуют их результаты и, по крайней мере, await их завершение.

public async Task CheckIds(IEnumerable<int> formIdList)
{
    var results = formIdList.Select(id => _userAccessService.HasAccessToFormId(id)).ToList();
    while (results.Any())
    {
        var result = await Task.WhenAny(results);
        results.Remove(result);
        var authorized = await result;
        if (!authorized) throw new UnauthorizedAccessException();
    }
}

спасибо, я обновил свой вопрос, ища разъяснений по токену отмены (извините, я больше являюсь разработчиком интерфейса, поэтому здесь немного не в моей тарелке)

Bryan Dellinger 20.09.2018 19:45

@BryanDellinger, чтобы отменить, вам нужно будет полностью передать токен через HasAccessToFormId до фактического вызова API. Затем, когда вы хотите отменить, вызовите отмену в источнике токена отмены. Дополнительная информация

JSteward 20.09.2018 20:26

о, думаю, я не могу пойти по этому пути, так как у меня нет доступа к api

Bryan Dellinger 20.09.2018 20:28

Не api, вам просто нужно побеспокоиться о вызове api с вашей стороны

JSteward 20.09.2018 20:29

Другие вопросы по теме