Perform all tasks at the same time and wait for their completion?

I have a number of asynchronous methods that I would like to execute at the same time. Each of these methods returns true or false as to whether they execute successfully or not. Their results are also recorded in our audit trail so that we can diagnose problems.

Some of my functions are independent of all of these successful methods, and we fully expect some of them to fail from time to time. If they do not work, the program will continue to run, and it will simply alert our support staff of the need to fix the problem.

I am trying to figure out what would be the best method for executing all these functions at the same time, and yet the parent function expects them only after they all start executing. The parent function will return Falseif ANY functions stop working and this will cause my application to stop executing.

My idea was to do something similar to:

public async Task<bool> SetupAccessControl(int objectTypeId, int objectId, int? organizationId)
{
    using (var context = new SupportContext(CustomerId))
    {
        if (organizationId == null)
        {
            var defaultOrganization = context.Organizations.FirstOrDefault(n => n.Default);
            if (defaultOrganization != null)  organizationId = defaultOrganization.Id;
        }
    }

    var acLink = AcLinkObjectToOrganiation(organizationId??0,objectTypeId,objectId);

    var eAdmin = GrantRoleAccessToObject("eAdmin", objectTypeId, objectId);
    var defaultRole = GrantRoleAccessToObject("Default", objectTypeId, objectId);

    await acLink;
    await eAdmin;
    await defaultRole;

    var userAccess = (objectTypeId != (int)ObjectType.User) || await SetupUserAccessControl(objectId);

    return acLink.Result && eAdmin.Result && defaultRole.Result && userAccess;
}

public async Task<bool> SetupUserAccessControl(int objectId)
{
    var everyoneRole = AddToUserRoleBridge("Everyone", objectId);
    var defaultRole = AddToUserRoleBridge("Default", objectId);

    await everyoneRole;
    await defaultRole;

    return everyoneRole.Result && defaultRole.Result;
}

Is there a better option? Do I have to restructure somehow? I'm just trying to speed up the execution, as I have a parent function that performs about 20 other functions that are independent of each other. Even so, more slowly, without async, execution takes only 1-2 seconds. However, this will be reduced so that ultimately this parent call is executed several hundred times (bulk inserts).

+4
1

, ( , ). .

, , , Task.WhenAll, . , :

async Task<bool> SetupUserAccessControlAsync(int objectId)
{
    var everyoneRoleTask = AddToUserRoleBridgeAsync("Everyone", objectId);
    var defaultRoleTask = AddToUserRoleBridgeAsync("Default", objectId);

    await Task.WhenAll(everyoneRoleTask, defaultRoleTask)

    return await everyoneRoleTask && await defaultRoleTask;
}

, , async Task.Run ThreadPool:

async Task<bool> SetupUserAccessControlAsync(int objectId)
{
    var everyoneRoleTask = Task.Run(() => AddToUserRoleBridgeAsync("Everyone", objectId));
    var defaultRoleTask = Task.Run(() => AddToUserRoleBridgeAsync("Default", objectId));

    await Task.WhenAll(everyoneRoleTask, defaultRoleTask)

    return await everyoneRoleTask && await defaultRoleTask;
}

bool, , Task.WhenAll , true:

async Task<bool> SetupUserAccessControlAsync(int objectId)
{
    var tasks = new List<Task<bool>>();
    tasks.Add(AddToUserRoleBridgeAsync("Everyone", objectId));
    tasks.Add(AddToUserRoleBridgeAsync("Default", objectId));

    return (await Task.WhenAll(tasks)).All(_ => _);
}
+6

Source: https://habr.com/ru/post/1610295/


All Articles