2

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

这里有一些小例子

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请求更改为async后,它不工作 - 在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); 



     } 
+0

凡将这个代码活你们是否在一个MVC网站的请求,如果是这样? ,请求来自哪里? –

+0

实际上我是从不同的web API请求的 是的,我正在开发目前在azure应用服务中托管的mvc站点。 – TDM

+0

我根据您的MakeRequest实现修改了我的答案。 。这应该可以解决你正在努力完成的任务。 –

回答

0

您想要先将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/

+0

大的假设。如果它不存在,可以使用任务对象异步调用它(请参阅我的回答) –

+0

使用Task.Run是不好的做法,不应使用。请参阅http://stackoverflow.com/questions/33764366/is-task-run-considered-bad-practise-in-an-asp-net-mvc-web-application –

+0

我编辑了我的代码,现在有我的makerequest function.i现在认为它很容易引用。 – TDM

-1
​​

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

+0

请你能解释一下这个方法吗?这是多线程吗? – TDM

+0

这真的取决于代码的居住地点。如果这是IIS托管的。开始一个新线程是不好的做法。 –

+0

这不是多线程。这只是异步调用。 –