异步服务门面在.NET 4.5 [英] Async service facade in .NET 4.5

查看:110
本文介绍了异步服务门面在.NET 4.5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚升级到.NET 4.5,我想利用异步方法的功能优势。具体来说,我有一个门面,使4种不同的API调用和聚集的反应成从我的控制器返回一个响应对象。因为这4个呼叫不相关,它们可以asyncronously完成和并行执行。我见过异步控制器的例子,但我想并行调用外观类本身内发生。这是我迄今:

在Facade.cs:

 公共异步任务<&字典LT;字符串对象>> AggregateServiceResponses(字符串authTicket)
    {
        VAR aggregateServiceResponse =新词典<字符串对象>();
        VAR asyncManager =新AsyncManager();        asyncManager.OutstandingOperations.Increment(4);        等待任务<&字典LT;字符串对象>> .Factory.StartNew(()=>
            {
                返回_membershipServiceManager.GetMemberResponse(authTicket);
            })ContinueWith(T =>
                {
                    asyncManager.Parameters [memberInfoResponse] = t.Result;
                    asyncManager.OutstandingOperations.Decrement();
           });
        等待任务< KeywordingResponseObject []> .Factory.StartNew(()=>
            {
                返回_keywordingServiceManager.GetKeywordResponse();
            })ContinueWith(T =>
        {
            asyncManager.Parameters [关键词] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });
        等待任务< FamilyResponseObject []> .Factory.StartNew(()=>
        {
            返回_familyServiceManager.GetFamilyResponse();
        })ContinueWith(T =>
        {
            asyncManager.Parameters [家] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });
        等待任务<&IEnumerable的LT;朋友>> .Factory.StartNew(()=>
        {
            返回_friendsServiceManager.GetFriendsResponse();
        })ContinueWith(T =>
        {
            asyncManager.Parameters [朋友] = t.Result;
            asyncManager.OutstandingOperations.Decrement();
        });       //所有服务电话完成后...构建复合的响应...        aggregateServiceResponse.Add(MemberInformation,asyncManager.Parameters [memberInfoResponse]);
        aggregateServiceResponse.Add(关键词,asyncManager.Parameters [关键词]);
        aggregateServiceResponse.Add(家庭,asyncManager.Parameters [家]);
        aggregateServiceResponse.Add(老友记,asyncManager.Parameters [老友记]);        返回aggregateServiceResponse;
    }


解决方案

可以做到这一点兼任例如:

  VAR memberTask = Task.Run(()=> ...);
VAR kewordTask = Task.Run(()=> ...);
VAR familyResponseTask = Task.Run(()=> ...);
VAR friendsTask = Task.Run(()=> ...);等待Task.WhenAll(memberTask,keywordTask,familyResponseTask,friendsTask);

不过,我必须指出的是,建议不要在ASP.NET并行​​(CPU绑定)处理,除非你只并发用户请求一把写仅供内部使用的服务。

您也不必使用 AsyncManager (或 AsyncController )了。

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;
    }

解决方案

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.

这篇关于异步服务门面在.NET 4.5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆