首页 > 解决方案 > task.run 为 c# 并行运行

问题描述

目前我有以下 foreach 循环

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

试图弄清楚如何做更多的任务。whenall 类型的构造,以便所有函数可以并行运行,如果有任何函数为 var hasaccess 返回 false,则抛出未经授权的异常。

/******************************取消令牌的更新问题************

使用下面的 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();
        }
    }

标签: c#asp.netasync-awaittask

解决方案


这个怎么样,它会抛出第一个未经授权的ID。但是,这里没有办法取消另一个请求,所以它们被简单地忽略了。我建议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();
    }
}

推荐阅读