【问题标题】:Is there a way to process multiple xml feeds asynchoronously?有没有办法异步处理多个 xml 提要?
【发布时间】:2020-06-17 09:49:03
【问题描述】:

我正在使用 Atom10FeedFormatter 类来处理调用 OData Rest API 端点的 atom xml 提要。

它工作正常,但如果提要中有超过 200 个条目,api 给出的结果很慢。

这就是我使用的:

        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统计feed的个数,将feed结果分成20个block,在endpoint 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 返回 void,因此我不能将它与 Task 一起使用。

如何解决这个问题,如何同时读取多个 xml 提要?

【问题讨论】:

    标签: asynchronous task odata xmlreader atom-feed


    【解决方案1】:

    通常我会使用对 api 的异步调用(本例中 numberofblocks = 26 个并行调用),但我不知道该怎么做。 formatter.ReadFrom 返回 void,因此我不能将它与 Task 一起使用。

    Atom10FeedFormatter 在这一点上是一个非常过时的类型,它不支持异步。也不太可能更新以支持异步。

    如何解决这个问题,如何同时读取多个 xml 提要?

    由于您被困在同步世界中,因此您可以选择使用“假异步”。这只是意味着您将在线程池线程上执行同步阻塞工作,并将这些操作中的每一个视为异步操作。即:

    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);
    

    【讨论】:

    • 谢谢,我会试试的。 :)
    • 成功了!另外,我在 for 循环中的代码中犯了一个错误。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多