Заполнить список с подэлементами async, заставляет список заморозить - PullRequest
2 голосов
/ 18 февраля 2012

Я пытаюсь заполнить список списком проектов, который содержит список конфигураций.

Итак, я пытаюсь сначала заполнить список моим списком проектов и всеми подпунктами. Все идет хорошо. Но для каждой конфигурации мне нужно сделать звонок в службу отдыха, чтобы получить статус. Поэтому я не хочу делать все эти запросы одновременно (сначала связывайте проекты и конфигурации, а затем для каждого состояния получения конфигурации и обновляйте асинхронное свойство состояния конфигурации. Но когда я начинаю загружать все конфигурации (может быть до приблизительно 200) список останавливается.

КРАСНЫЙ: Подумав, лучше загрузить статус каждого элемента списка (подэлемента), когда он станет видимым для пользователя, однако я не могу найти для этого хороших событий. Любые предположения о том, как справиться с этим?

Вот мое решение:

MainViewModel
//Fired on pageLoad
_projectRepository.FindBy(_serverCityConfiguration, BuildListBoxGroups);


    private void BuildListBoxGroups(IEnumerable<Project> projects)
    {
        var projectGroups = new List<ListBoxGroup<BuildConfigurationModel>>();

        foreach (Project project in projects)
        {
            var buildConfigurations = project.BuildConfigurations.Select(buildConfiguration 
                => new BuildConfigurationModel(buildConfiguration.Id, buildConfiguration.Name, new List<BuildModel>())).ToList();
            projectGroups.Add(new ListBoxGroup<BuildConfigurationModel>(
                new ProjectModel(project.Id, project.Name), buildConfigurations));
        }
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                  Projects = projectGroups.ToObservableCollection());

        //It's here my problem starts, where my listbox freezes
        ThreadPool.QueueUserWorkItem(FireBuildsFetching, projects);

    }

    private void FireBuildsFetching(object stuff)
    {
        var projects = stuff as IEnumerable<Project>;
        foreach (var project in projects)
        {
            foreach (var buildConfiguration in project.BuildConfigurations)
            {
                ThreadPool.QueueUserWorkItem(RetrieveBuils, buildConfiguration);
            }
        }
    }

    private void RetrieveBuils(object buildConfiguration)
    {
        Debug.WriteLine("RetrieveBuils");
        var localBuildConfig = buildConfiguration as BuildConfiguration;

        //Here is some logic to find correct buildconfiguration to add status to
        ...
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                          buildConfigurationModel.AddBuilds(buildModels));                                                                                    

     }

Когда все вызовы на обслуживание завершены, список обновляется сразу всеми статусами.

У кого-нибудь есть хорошие решения моей проблемы?

1 Ответ

0 голосов
/ 26 февраля 2012

Можете ли вы добавить ожидание (thread.Sleep) 50 мс в фоновый цикл. Мне кажется, ваш список постоянно обновляется фоновой угрозой. Выделение из потоков + обновление утверждений пользовательского интерфейса требует ресурсов. Оптимизация кода за счет минимизации количества обращений и пакетного обновления данных (на 10 или 20 элементов) может помочь. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...