1

我目前正在 C# Xamarin 中构建媒体源。

媒体提要是单个帖子的数据模型的可观察集合。

我使用的 API 相当有限,所以我无法正确查询来指定我想要的数据,这意味着我最终会得到很多数据。为了确保用户真正获得足够的内容,我的集合需要请求 100 到 500 个元素之间的任何地方。

这使得加载时间非常长,我希望在从 API 检索数据的同时返回集合以不断更新媒体提要。

饲料管理器

 public static async Task<ObservableCollection<PostPresenter>> GetFeed(ApiClient client, string account, int limit = 100)
    {
        var feed = new ObservableCollection<PostPresenter>();

        var feedResult = await ApiClient.FeedClient.GetFeed(account, limit: limit);

        if (feedResult != null)
        {
            foreach (var feedObj in feedResult.Result)
            {


                if (feedObj != null)
                {

                    var comment = feedObj;
                    feed.Add(new PostPresenter()
                    {
                        Username = comment.Author,
                        Description = comment?.Title ?? comment.Body?.TruncateString(15) ?? "",
                        Media = comment.JsonMetadata.Image != null ? comment?.JsonMetadata?.Image.FirstOrDefault() : null,
                        Tags = comment?.JsonMetadata?.Tags.ToList() ?? new List<string> { "" },
                        PostTime = comment?.Created.ToString(),
                        Permlink = comment.Permlink,
                        EntryId = feedObj.Id


                    });



                }

            }
        }
        foreach (var testObj in feed)
        {
            await GetFeedMetadata(client, testObj);
        }

        return feed;
    }

主页/提要页面

 var tempFeedEntries = await FeedManager.GetFeed(User.ApiClient, User.Username);
                //var tempFeedEntries = await FeedManager.GetAllFeedData(User.ApiClient, Feed);
                if (tempFeedEntries != null)
                {
                    foreach(var tempFeedEntry in tempFeedEntries)
                    {
                        Feed.Add(tempFeedEntry);
                        IsLoading = false;
                        FeedListViewLoading.IsRunning = false;
                        FeedListViewLoading.IsRunning = false;

                        await FeedManager.GetAllFeedData(User.ApiClient, tempFeedEntries);
                        FeedListView.ItemsSource = Feed;
                    }

                }

如何在不等待加载每个元素的情况下返回集合或帖子的临时副本以填充提要?

4

1 回答 1

2

您可以在这里做很多事情,但是您不能做的一件事yield方法中使用async

我建议使用TPL DataFlow,. 基本上, Dataflow允许您构建管道处理器。

您可以创建一个为其他作业返回信息的作业,该作业返回其他作业的信息等等。

优点是,

  • 它可以很好地工作asyncawait这意味着您可以非常有效地并行执行此任务。

  • 因为这些看似 IO 工作负载,它将有效地使用 IO 完成端口而不是线程池来非常有效地扩展它。

  • 您可以设想设置最大并行度以允许将其分解 10 到 100 次(或更多)次,而无需任何额外的代码或开销,进而同时从您的提要(和元数据)中获取所有数据而无需等待线程。

  • 您可以指定它以确保顺序,这意味着它将并行工作并按顺序为管道中的下一个处理器返回结果。

  • 你可以用一个动作块(非线程)结束它,它可以ObserverableCollection用 AddRange 更新你的(虽然我忘记了该方法是否会通知),你还需要使用Invoke.

即使有编组的缺点,DataFlow 也会通过几个因素以非常少的代码使其更高效和响应更快。

不幸的是,没有足够的关于你的类型、API 和环境的信息让我把一个小例子放在一起。但是,我真的建议您克服学习曲线并学习这个宝贵的TPL资源和库。

于 2019-03-04T02:31:47.920 回答