我正在尝试从我的服务器进行大量调用到另一台服务器公开的REST API,但代码运行时间太长。
下面是需要花费大量时间的代码。现在我正在使用C#Async/Await
和HTTPClient
,我有更好的方法吗?
static async Task RunAsync()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
foreach (var workbk in (workbooksforuserresultingMessage.Items[1] as workbookListType).workbook)
{
if (workbk.project.name == "Ascend")
{
tsResponse viewresultingMessage = null;
//Get View Data
HttpRequestMessage viewrequestMessage = new HttpRequestMessage(HttpMethod.Get, "sites/" + ((siteresultingMessage.Items[0] as siteType).id.ToString()) + "/workbooks/" + workbk.id + "/views");
// Add our custom headers
viewrequestMessage.Headers.Add("X-Tableau-Auth", (resultingMessage.Items[0] as credentialsType).token.ToString());
HttpResponseMessage viewrequestMessageresponse = await client.SendAsync(viewrequestMessage);
if (viewrequestMessageresponse.IsSuccessStatusCode)
{
var viewresponsecontent = await viewrequestMessageresponse.Content.ReadAsStringAsync();
XmlSerializer siteserializer = new XmlSerializer(typeof(tsResponse));
using (TextReader reader = new StringReader(viewresponsecontent))
{
viewresultingMessage = (tsResponse)siteserializer.Deserialize(reader);
}
}
}
}
foreach (var workbk in (workbooksforuserresultingMessage.Items[1] as workbookListType).workbook)
{
if (workbk.project.name == "Ascend")
{
foreach (var vu in workbk.views)
{
tsResponse viewImageresultingMessage = null;
//Get View Data
HttpRequestMessage viewImagerequestMessage = new HttpRequestMessage(HttpMethod.Get, "sites/" + ((siteresultingMessage.Items[0] as siteType).id.ToString()) + "/workbooks/" + workbk.id + "/views/" + vu.id + "/previewImage");
// Add our custom headers
viewImagerequestMessage.Headers.Add("X-Tableau-Auth", (resultingMessage.Items[0] as credentialsType).token.ToString());
HttpResponseMessage viewImagewrequestMessageresponse = await client.SendAsync(viewImagerequestMessage);
if (viewImagewrequestMessageresponse.IsSuccessStatusCode)
{
var viewImageresponsecontent = await viewImagewrequestMessageresponse.Content.ReadAsByteArrayAsync();
XmlSerializer siteserializer = new XmlSerializer(typeof(tsResponse));
using (var ms = new MemoryStream(viewImageresponsecontent))
{
Image returnImage = Image.FromStream(ms);
//return returnImage;
}
}
}
}
}
}
答案 0 :(得分:0)
等待你的循环中的那些将序列化请求。考虑在任务上使用.ContinueWith来对结果进行一些处理,跟踪数组中的任务,然后在完成所有并行工作后调用Task.WhenAll。
答案 1 :(得分:0)
await
,执行就会有效地“暂停”,并且在Task
完成之前不会恢复。您可以通过不等待Task
来避免这种情况,只需将其添加到要跟踪的任务列表中即可。
为了方便这一点,我认为如果您引入了几个辅助方法来执行循环体并返回Task
,这将有所帮助。
public Task<tsResponse> GetViewString(HttpRequestMessage viewrequestMessage)
{
tsResponse viewresultingMessage = null;
HttpResponseMessage viewrequestMessageresponse = await client.SendAsync(viewrequestMessage);
if (viewrequestMessageresponse.IsSuccessStatusCode)
{
var viewresponsecontent = await viewrequestMessageresponse.Content.ReadAsStringAsync();
XmlSerializer siteserializer = new XmlSerializer(typeof(tsResponse));
using (TextReader reader = new StringReader(viewresponsecontent))
{
viewresultingMessage = (tsResponse)siteserializer.Deserialize(reader);
}
}
return viewresultingMessage;
}
public Task<tsResponse> GetViewImage(HttpRequestMessage viewImagerequestMessage)
{
tsResponse viewImageresultingMessage = null;
//Get View Data
HttpResponseMessage viewImagewrequestMessageresponse = await client.SendAsync(viewImagerequestMessage);
if (viewImagewrequestMessageresponse.IsSuccessStatusCode)
{
var viewImageresponsecontent = await viewImagewrequestMessageresponse.Content.ReadAsByteArrayAsync();
XmlSerializer siteserializer = new XmlSerializer(typeof(tsResponse));
using (var ms = new MemoryStream(viewImageresponsecontent))
{
return Image.FromStream(ms);
}
}
}
然后在主循环中,您只需在方法启动时将任务添加到列表中,这将基本上并行执行任务。如果服务器导致问题,您可能需要增加服务器可以进行的并发连接数。然后你的主要方法就变成了。
static async Task RunAsync()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
var tasks = new List<Task<tsResponse>>();
foreach (var workbk in (workbooksforuserresultingMessage.Items[1] as workbookListType).workbook)
{
if (workbk.project.name == "Ascend")
{
tsResponse viewresultingMessage = null;
//Get View Data
HttpRequestMessage viewrequestMessage = new HttpRequestMessage(HttpMethod.Get, "sites/" + ((siteresultingMessage.Items[0] as siteType).id.ToString()) + "/workbooks/" + workbk.id + "/views");
// Add our custom headers
viewrequestMessage.Headers.Add("X-Tableau-Auth", (resultingMessage.Items[0] as credentialsType).token.ToString());
tasks.Add(GetViewString(viewrequestMessage);
}
}
foreach (var workbk in (workbooksforuserresultingMessage.Items[1] as workbookListType).workbook)
{
if (workbk.project.name == "Ascend")
{
foreach (var vu in workbk.views)
{
tsResponse viewImageresultingMessage = null;
//Get View Data
HttpRequestMessage viewImagerequestMessage = new HttpRequestMessage(HttpMethod.Get, "sites/" + ((siteresultingMessage.Items[0] as siteType).id.ToString()) + "/workbooks/" + workbk.id + "/views/" + vu.id + "/previewImage");
// Add our custom headers
viewImagerequestMessage.Headers.Add("X-Tableau-Auth", (resultingMessage.Items[0] as credentialsType).token.ToString());
tasks.Add(GetViewImage(viewImagerequestMessage);
}
}
}
// wait for all the tasks to complete (non blocking)
await Task.WhenAll(tasks);
}