Async service facade in .NET 4.5

2019-08-04 15:34发布

I just upgraded to .NET 4.5 and I want to take advantage of the asynchronous method features. Specifically, I have a facade that makes 4 different api calls and aggregates the responses into a single response object which will be returned from my controller. Since these 4 calls aren't related, they can be done asyncronously and execute in parallel. I've seen examples of asynchronous controllers, but I want the parallel calls to occur within the facade class itself. This is what I have thus far:

In Facade.cs:

    public async Task<Dictionary<string, object>> AggregateServiceResponses(string authTicket)
    {
        var aggregateServiceResponse = new Dictionary<string, object>();
        var asyncManager = new AsyncManager();

        asyncManager.OutstandingOperations.Increment(4);

        await Task<Dictionary<string, object>>.Factory.StartNew(() =>
            {
                return _membershipServiceManager.GetMemberResponse(authTicket);
            }).ContinueWith(t =>
                {
                    asyncManager.Parameters["memberInfoResponse"] = t.Result;
                    asyncManager.OutstandingOperations.Decrement();
           });


        await Task<KeywordingResponseObject[]>.Factory.StartNew(() =>
            {
                return _keywordingServiceManager.GetKeywordResponse();
            }).ContinueWith(t =>
        {
            asyncManager.Parameters["Keywords"] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });


        await Task<FamilyResponseObject[]>.Factory.StartNew(() =>
        {
            return _familyServiceManager.GetFamilyResponse();
        }).ContinueWith(t =>
        {
            asyncManager.Parameters["Family"] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });


        await Task<IEnumerable<Friends>>.Factory.StartNew(() =>
        {
            return _friendsServiceManager.GetFriendsResponse();
        }).ContinueWith(t =>
        {
            asyncManager.Parameters["Friends"] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });

       //After all service calls complete...build composite response...

        aggregateServiceResponse.Add("MemberInformation",asyncManager.Parameters["memberInfoResponse"]);
        aggregateServiceResponse.Add("Keywords", asyncManager.Parameters["Keywords"] );
        aggregateServiceResponse.Add("Family", asyncManager.Parameters["Family"]);
        aggregateServiceResponse.Add("Friends",asyncManager.Parameters["Friends"]);

        return aggregateServiceResponse;
    }

1条回答
SAY GOODBYE
2楼-- · 2019-08-04 16:31

You can do this concurrently as such:

var memberTask = Task.Run(() => ...);
var kewordTask = Task.Run(() => ...);
var familyResponseTask = Task.Run(() => ...);
var friendsTask = Task.Run(() => ...);

await Task.WhenAll(memberTask, keywordTask, familyResponseTask, friendsTask);

However, I must point out that parallel (CPU-bound) processing on ASP.NET is not recommended unless you are writing an internal-only service with only a handful of concurrent user requests.

You also don't need to use AsyncManager (or AsyncController) anymore.

查看更多
登录 后发表回答