繁体   English   中英

用于多个API调用的Asp.net MVC4并行编程

[英]Asp.net MVC4 Parallel Programming for multiple API calls

我有一些关于ASP .NET MVC 4并行编程的问题。 我想使用并行编程,因为同时从多个API调用接收数据。

以下是一些小例子

RootObjectRS fairsearchRS1 = new RootObjectRS();
RootObjectRS fairsearchRS2 = new RootObjectRS();
RootObjectRS fairsearchRS3 = new RootObjectRS();

fairsearchRS1 = MakeRequest(searchUrl, WWWToken, request.TripType1, request.TripfromAirPort1, request.TriptoAirPort1, request.FlyfromDate1, request.FlytoDate1, request.Flyclass, request.Passengers, starting, reqstid);        
fairsearchRS2 = MakeRequest(searchUrl, WWWToken, request.TripType2, request.TripfromAirPort2, request.TriptoAirPort2, request.FlyfromDate2, request.FlytoDate2, request.Flyclass, request.Passengers, starting, reqstid);        
fairsearchRS3 = MakeRequest(searchUrl, WWWToken, request.TripType3, request.TripfromAirPort3, request.TriptoAirPort3, request.FlyfromDate3, request.FlytoDate3, request.Flyclass, request.Passengers, starting, reqstid);

这只是我的代码的一个小例子。 使用make请求我正在调用这些API,并从中获取数据并将其绑定到那些rootobjectRS对象。

现在我一个接一个地发送这些请求。 但我需要同时这样做,我需要等到这3个请求数据到达。

那么我应该如何使用并行或其他编程方法来解决这个问题? 因为现在需要1分钟。 但如果我同时这样做,那么我可以在20秒内完成。 这是主要的事情,节省时间。

我不知道ASP .NET MVC4是否可以实现这种并行编程概念。 但如果有人可以给我支持,那将是很有帮助的。 至少一些好的教程也很有帮助。

编辑

实际上这是我的makeRequest函数,

 public static RootObjectRS MakeRequest(string requestUrl, SeneruUBT.Models.TokenModels token, string triptype, string from, string to, string flyin, string flyout, string flyclass, string passengers, DateTime starting, int reqstid)
        {

            HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/json";
            request.Headers.Add("Authorization", token.token_type + " " + token.access_token);
            request.Accept = "application/json";

            string ttrip = triptype;

            var streamWriter = new StreamWriter(request.GetRequestStream());

            if (ttrip.Equals("OneWay"))
            {
                RootObject searchBFMRQO = CreateRequestObjectOneWay(triptype, from, to, flyin, flyclass, passengers);
                String searchString = JsonConvert.SerializeObject(searchBFMRQO);
                streamWriter.Write(JsonConvert.SerializeObject(searchBFMRQO));

                streamWriter.Flush();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            var httpResponse = (HttpWebResponse)request.GetResponse();
            int sc = (int)httpResponse.StatusCode;
            System.Diagnostics.Debug.Write(sc);
            if (httpResponse.StatusCode != HttpStatusCode.OK)
            {

                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    var result = streamReader.ReadToEnd();
                    RootObjectRS errorresult = JsonConvert.DeserializeObject<RootObjectRS>(result);

                    return (errorresult);
                }
            }
            else
            {
                var resp = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();

                RootObjectRS searchResponse = JsonConvert.DeserializeObject<RootObjectRS>(resp.ToString());

                SearchResponseFlightService ResponsFlSer = null;
                ResponsFlSer = new SearchResponseFlightService(new UBTRepository.UBTUnitofWorks(new UBTRepository.TravelEntities()));
                SearchResponseFlight ReFl = new SearchResponseFlight();


                ReFl.searchRequestID = reqstid;
                ReFl.StopQuantity = "1";
                ReFl.responseJson = resp.ToString();
                DateTime ending = DateTime.Now;
                ReFl.responseDuration = ending.Subtract(starting).Milliseconds;
                ReFl.starttimestamp = starting;

                ReFl.endtimestamp = ending;

                ResponsFlSer.Add(ReFl);

                searchResponse.reqid = reqstid;

                return (searchResponse);
            }


        }

我认为现在可能有点容易理解。


在将我的make请求更改为异步后,它不起作用 - 在MakeRequestAsync中给出错误。

 public static async Task RootObjectRS MakeRequestAsync(string requestUrl, SeneruUBT.Models.TokenModels token, string triptype, string from, string to, string flyin, string flyout, string flyclass, string passengers, DateTime starting, int reqstid)
    {

        HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
        request.Method = "POST";
        request.ContentType = "application/json";
        request.Headers.Add("Authorization", token.token_type + " " + token.access_token);
        request.Accept = "application/json";

        string ttrip = triptype;

        var streamWriter = new StreamWriter(await request.GetRequestStreamAsync());

        if (ttrip.Equals("OneWay"))
        {
            RootObject searchBFMRQO = CreateRequestObjectOneWay(triptype, from, to, flyin, flyclass, passengers);
            String searchString = JsonConvert.SerializeObject(searchBFMRQO);
            streamWriter.Write(JsonConvert.SerializeObject(searchBFMRQO));

            streamWriter.Flush();
        }
        HttpWebResponse response = await (HttpWebResponse)request.GetResponseAsync();
        var httpResponse = await (HttpWebResponse)request.GetResponseAsync();
        int sc = (int)httpResponse.StatusCode;
        System.Diagnostics.Debug.Write(sc);

            var resp = new StreamReader(await httpResponse.GetResponseStreamAsync()).ReadToEnd();

            RootObjectRS searchResponse = JsonConvert.DeserializeObject<RootObjectRS>(resp.ToString());

            SearchResponseFlightService ResponsFlSer = null;
            ResponsFlSer = new SearchResponseFlightService(new UBTRepository.UBTUnitofWorks(new UBTRepository.TravelEntities()));
            SearchResponseFlight ReFl = new SearchResponseFlight();


            ReFl.searchRequestID = reqstid;
            ReFl.StopQuantity = "1";
            ReFl.responseJson = resp.ToString();
            DateTime ending = DateTime.Now;
            ReFl.responseDuration = ending.Subtract(starting).Milliseconds;
            ReFl.starttimestamp = starting;

            ReFl.endtimestamp = ending;

            ResponsFlSer.Add(ReFl);

            searchResponse.reqid = reqstid;

            return (searchResponse);



        }

您想首先将MakeRequest修改为MakeRequestAsync。 基本上,只要该方法访问某些I / O操作,Microsoft就会提供异步版本。 (阅读下面的文章,了解它的作用)

public static async Task<RootObjectRS> MakeRequestAsync(string requestUrl, SeneruUBT.Models.TokenModels token, string triptype, string from, string to, string flyin, string flyout, string flyclass, string passengers, DateTime starting, int reqstid)
    {

        HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
        request.Method = "POST";
        request.ContentType = "application/json";
        request.Headers.Add("Authorization", token.token_type + " " + token.access_token);
        request.Accept = "application/json";

        string ttrip = triptype;

        var streamWriter = new StreamWriter(await request.GetRequestStreamAsync());

        if (ttrip.Equals("OneWay"))
        {
            RootObject searchBFMRQO = CreateRequestObjectOneWay(triptype, from, to, flyin, flyclass, passengers);
            String searchString = JsonConvert.SerializeObject(searchBFMRQO);
            streamWriter.Write(JsonConvert.SerializeObject(searchBFMRQO));

            streamWriter.Flush();
        }
        HttpWebResponse response = await (HttpWebResponse)request.GetResponseAsync();
        var httpResponse = await (HttpWebResponse)request.GetResponseAsync();
        int sc = (int)httpResponse.StatusCode;
        System.Diagnostics.Debug.Write(sc);
        if (httpResponse.StatusCode != HttpStatusCode.OK)
        {

            using (var streamReader = new StreamReader(await httpResponse.GetResponseStreamAsync()))
            {
                var result = streamReader.ReadToEnd();
                RootObjectRS errorresult = JsonConvert.DeserializeObject<RootObjectRS>(result);

                return (errorresult);
            }
        }
        else
        {
            var resp = new StreamReader(await httpResponse.GetResponseStreamAsync()).ReadToEnd();

            RootObjectRS searchResponse = JsonConvert.DeserializeObject<RootObjectRS>(resp.ToString());

            SearchResponseFlightService ResponsFlSer = null;
            ResponsFlSer = new SearchResponseFlightService(new UBTRepository.UBTUnitofWorks(new UBTRepository.TravelEntities()));
            SearchResponseFlight ReFl = new SearchResponseFlight();


            ReFl.searchRequestID = reqstid;
            ReFl.StopQuantity = "1";
            ReFl.responseJson = resp.ToString();
            DateTime ending = DateTime.Now;
            ReFl.responseDuration = ending.Subtract(starting).Milliseconds;
            ReFl.starttimestamp = starting;

            ReFl.endtimestamp = ending;

            ResponsFlSer.Add(ReFl);

            searchResponse.reqid = reqstid;

            return (searchResponse);
        }


    }

上面的方法可以使用一些重构(它中有很多东西=))

现在MakeRequestAsync存在,请修改下面的代码。

RootObjectRS fairsearchRS1 = new RootObjectRS();
RootObjectRS fairsearchRS2 = new RootObjectRS();
RootObjectRS fairsearchRS3 = new RootObjectRS();

var fairsearchRS1Task = MakeRequestAsync(searchUrl, WWWToken, request.TripType1, request.TripfromAirPort1, request.TriptoAirPort1, request.FlyfromDate1, request.FlytoDate1, request.Flyclass, request.Passengers, starting, reqstid);        
var fairsearchRS2Task = MakeRequestAsync(searchUrl, WWWToken, request.TripType2, request.TripfromAirPort2, request.TriptoAirPort2, request.FlyfromDate2, request.FlytoDate2, request.Flyclass, request.Passengers, starting, reqstid);        
var fairsearchRS3Task = MakeRequestAsync(searchUrl, WWWToken, request.TripType3, request.TripfromAirPort3, request.TriptoAirPort3, request.FlyfromDate3, request.FlytoDate3, request.Flyclass, request.Passengers, starting, reqstid);

fairsearchRS1 = await fairsearchRS1Task;
fairsearchRS2 = await fairsearchRS2Task;
fairsearchRS3 = await fairsearchRS3Task;    

注意:您不想执行Task.Run之类的操作。 这将创建一个新线程。 看这个摘录:

“async和await关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不能在自己的线程上运行。该方法在当前同步上下文上运行并在线程上使用时间只有当方法处于活动状态时才可以使用Task.Run将CPU绑定的工作移动到后台线程,但后台线程对于只等待结果可用的进程没有帮助。“

来自: https//msdn.microsoft.com/en-us/library/mt674882.aspx

启动一个新的线程,IIS托管的应用程序是不好的做法。 请参阅: https//blogs.msdn.microsoft.com/tmarq/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications/

    var tasks = new Task[] {
        Task.Run(() => MakeRequest()),
        Task.Run(() => MakeRequest()),
        Task.Run(() => MakeRequest())
        };

    Task.WaitAll(tasks);

Task.Run可能不是应用异步模式的适当方法。 找到为三个长时间运行的呼叫执行ansync模式的正确方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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