Непрерывное возвращение Observablecollection для медиа-канала C # xamarin - PullRequest
0 голосов
/ 04 марта 2019

В настоящее время я создаю ленту мультимедиа в 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;
                    }

                }

Как вернуть временную копию коллекции или сообщений, чтобы заполнить канал, не дожидаясь загрузки каждого элемента?

1 Ответ

0 голосов
/ 04 марта 2019

Есть много вещей, которые вы могли бы здесь сделать, однако одну вещь, которую вы не можете сделать, это использовать yield в методе async.

Я бы предложил использовать TPL DataFlow, .В основном Dataflow позволяет создавать конвейерные процессоры.

Вы можете создать задание, которое возвращает информацию для других заданий, которое возвращает информацию для других заданий и т. Д.

Преимущества:

  • Хорошо работает с async и await, что означает, что вы можете очень эффективно выполнять параллельное выполнение этой задачи.

  • Поскольку это, по-видимому, рабочие нагрузки ввода-вывода, он будет эффективно использовать порты завершения ввода-вывода, а не пул потоков для очень эффективного масштабирования.

  • Можно предусмотреть установку максимальной степени параллелизма, чтобы это значение можно было разбить на 10–100 (или более) раз без какого-либо дополнительного кода или дополнительных затрат, получая в свою очередь все данныеиз вашего фида (и метаданных) все одновременно без удержания потоков.

  • Вы можете указать его, чтобы обеспечить порядок, то есть он будет работать параллельно, а также будет возвращать результаты для следующего процессорав конвейере последовательно.

  • Вы можете завершить его блоком действий (без резьбы), который может обновить ваш ObserverableCollection с помощью AddRange (хотя я забыл, если этот метод уведомит), также вам нужно будет выполнить маршалс помощью Invoke.

Даже при недостатке маршаллинга DataFlow сделает это более эффективным и более отзывчивым благодаря нескольким факторам с минимальным кодом.

К сожалению, мне просто не хватает информации о ваших типах, API и среде, чтобы я смог собрать хотя бы маленький пример.Тем не менее, я действительно советую вам пройти курс обучения и изучить этот ценный ресурс TPL и библиотеку

...