有没有办法异步处理多个 xml 提要?
Is there a way to process multiple xml feeds asynchoronously?
我正在使用 Atom10FeedFormatter class 处理调用 OData Rest API 端点的原子 xml 提要。
它工作正常,但是 api 如果提要中的条目超过 200 个,结果会很慢。
这是我用的:
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
string odataurl= "http://{mysite}/_api/ProjectData/Projects";
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader);
}
foreach (SyndicationItem item in formatter.Feed.Items)
{
//processing the result
}
我想通过拆分原始请求来查询结果,跳过一些条目并限制条目大小,从而至少加快这个过程。
主要思想是使用 $count 计算提要的数量,将提要结果分成 20 个块,在端点 url 中使用 $skip 和 $top,遍历结果,最后总结一下。
int countoffeeds = 500; // for the sake of simplicity, of course, i get it from the odataurl using $count
int numberofblocks = (countoffeeds/20) + 1;
for(int i = 0; i++; i<numberofblocks){
int skip = i*20;
int top = 20;
string odataurl = "http://{mysite}/_api/ProjectData/Projects"+"?&$skip="+skip+"&top=20";
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader); // And this the part where I am stuck. It returns a void so I
//cannot use Task<void> and process the result later with await
}
...
通常我会使用对 api 的异步调用(这种情况下 numberofblocks = 26 并行调用),但我不知道该怎么做。 formatter.ReadFrom
returns 无效,因此我不能将它与任务一起使用。
如何解决这个问题,如何同时阅读多个 xml 供稿?
Normally I would use async calls to the api (this case numberofblocks = 26 calls in parallel), but I do not know how would I do that. formatter.ReadFrom returns void, thus I can not use it with Task.
Atom10FeedFormatter
在这一点上是一个非常过时的类型,它不支持异步。也不太可能更新为支持异步。
How can I solve this, and how can I read multiple xml feeds at the same time?
由于您陷入了同步世界,您可以选择使用 "fake asynchrony"。这只是意味着您将在线程池线程上执行同步阻塞工作,并将这些操作中的每一个都视为异步操作。即:
var tasks = new List<Task<Atom10FeedFormatter>>();
for(int i = 0; i++; i<numberofblocks) {
int skip = i*20;
int top = 20;
tasks.Add(Task.Run(() =>
{
string odataurl = "http://{mysite}/_api/ProjectData/Projects"+"?&$skip="+skip+"&top=20";
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader);
return formatter;
}
}));
}
var formatters = await Task.WhenAll(tasks);
我正在使用 Atom10FeedFormatter class 处理调用 OData Rest API 端点的原子 xml 提要。
它工作正常,但是 api 如果提要中的条目超过 200 个,结果会很慢。
这是我用的:
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
string odataurl= "http://{mysite}/_api/ProjectData/Projects";
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader);
}
foreach (SyndicationItem item in formatter.Feed.Items)
{
//processing the result
}
我想通过拆分原始请求来查询结果,跳过一些条目并限制条目大小,从而至少加快这个过程。
主要思想是使用 $count 计算提要的数量,将提要结果分成 20 个块,在端点 url 中使用 $skip 和 $top,遍历结果,最后总结一下。
int countoffeeds = 500; // for the sake of simplicity, of course, i get it from the odataurl using $count
int numberofblocks = (countoffeeds/20) + 1;
for(int i = 0; i++; i<numberofblocks){
int skip = i*20;
int top = 20;
string odataurl = "http://{mysite}/_api/ProjectData/Projects"+"?&$skip="+skip+"&top=20";
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader); // And this the part where I am stuck. It returns a void so I
//cannot use Task<void> and process the result later with await
}
...
通常我会使用对 api 的异步调用(这种情况下 numberofblocks = 26 并行调用),但我不知道该怎么做。 formatter.ReadFrom
returns 无效,因此我不能将它与任务一起使用。
如何解决这个问题,如何同时阅读多个 xml 供稿?
Normally I would use async calls to the api (this case numberofblocks = 26 calls in parallel), but I do not know how would I do that. formatter.ReadFrom returns void, thus I can not use it with Task.
Atom10FeedFormatter
在这一点上是一个非常过时的类型,它不支持异步。也不太可能更新为支持异步。
How can I solve this, and how can I read multiple xml feeds at the same time?
由于您陷入了同步世界,您可以选择使用 "fake asynchrony"。这只是意味着您将在线程池线程上执行同步阻塞工作,并将这些操作中的每一个都视为异步操作。即:
var tasks = new List<Task<Atom10FeedFormatter>>();
for(int i = 0; i++; i<numberofblocks) {
int skip = i*20;
int top = 20;
tasks.Add(Task.Run(() =>
{
string odataurl = "http://{mysite}/_api/ProjectData/Projects"+"?&$skip="+skip+"&top=20";
Atom10FeedFormatter formatter = new Atom10FeedFormatter();
using (XmlReader reader = XmlReader.Create(odataurl))
{
formatter.ReadFrom(reader);
return formatter;
}
}));
}
var formatters = await Task.WhenAll(tasks);