简体   繁体   中英

How to wait for all concurrent Tasks to complete in synchronous code .NET 4.5?

I have the following ServiceStack web service

public class RetreadServices : Service
{
    public IRepository Repository { get; set; }

    //http://stackoverflow.com/questions/18902135/servicestack-no-server-side-async-support

    public async Task<ValidationResponse> Get(RetreadSsnInfoAsync request)
    {
        return await Task.Factory.StartNew(() =>
        {
            Tenant.SetTenant(request.TenantId);
            return new ValidationResponse { Result = Repository.CannotRetreadSsn(request.Ssn) };                    
        });
    }

    public async Task<ValidationResponse> Get(RetreadEmailInfoAsync request)
    {
        return await Task.Factory.StartNew(() =>
        {
            Tenant.SetTenant(request.TenantId);
            return new ValidationResponse { Result = Repository.CannotRetreadEmail(request.Emails) };
        });
    }

    //more methods constructed in the same fashion

}

then in a separate class in my application I have this method (based off of code from @StephenCleary)

private async Task<ValidationResponse[]> DoOperationsConcurrentlyAsync(string tenantId, string[] emails, string ssn)
{
    Task<ValidationResponse>[] tasks =
    {
        ResolveService<RetreadServices>().Get(new RetreadEmailInfoAsync { TenantId = tenantId, Emails = emails }), 
        ResolveService<RetreadServices>().Get(new RetreadSsnInfoAsync { TenantId = tenantId, Ssn = ssn })
    };

    await Task.WhenAll(tasks);

    ValidationResponse[] result = new ValidationResponse[tasks.Length];

    return result;
}

and being invoked like this

synchronous code...
synchronous code...

var result = DoOperationsConcurrentlyAsync(request.TenantId, request.Emails, request.Ssn);

synchronous code...
synchronous code...

The goal of all of this is to wait while the tasks process in parallel and hopefully decrease my over-all time... but the DoOperationsConcurrentlyAsync needs to block, how do I do that? Then as a bonus, how do I pass the return values back from the individual tasks up and out of the method with the async modifier?

I hope I'm understanding this correctly. But don't you just need to add the await keyword?

synchronous code...
synchronous code...

var result = await DoOperationsConcurrentlyAsync(request.TenantId, request.Emails, request.Ssn);

synchronous code...
synchronous code...

EDIT: Bonus question: Again, I hope I'm understanding you correctly...

But I would replace this:

await Task.WhenAll(tasks);

ValidationResponse[] result = new ValidationResponse[tasks.Length];

return result;

...with simply this:

return await Task.WhenAll(tasks);

That should work the way you want it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM