我有一些关于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);
}
答案 0 :(得分: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这样的事情。这将创建一个新线程。见摘录:
&#34; async和await关键字不会导致创建其他线程。异步方法不需要多线程,因为异步方法不能在自己的线程上运行。该方法在当前同步上下文上运行,并仅在方法处于活动状态时在线程上使用时间。您可以使用Task.Run将受CPU限制的工作移动到后台线程,但后台线程对于等待结果可用的进程没有帮助。&#34;
来自: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/
答案 1 :(得分:-1)
var tasks = new Task[] {
Task.Run(() => MakeRequest()),
Task.Run(() => MakeRequest()),
Task.Run(() => MakeRequest())
};
Task.WaitAll(tasks);
Task.Run可能不是应用异步模式的合适方法。找到为三个长时间运行的呼叫执行ansync模式的正确方法。