Как выполнить поиск во время загрузки списка ItemCollection (ошибка: коллекция была изменена; операция перечисления может не выполняться.) - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть метод в потоке, который извлекает пользовательские изображения и связывает изображения со списком ItemCollection.в то время как изображения вытягиваются, я хочу иметь возможность поиска по списку.Я продолжаю получать эту ошибку, Коллекция была изменена;операция перечисления может не выполняться .Вот код извлечения изображения:

Thread reprintAppsThread = new Thread(() =>
    {
        var items = assignmentPage.reprintItemListView.Items;
        foreach (EcofOApplicationObject obj in items)
        {
            byte[] userPassport;
            bool fetched = userPassports.TryGetValue(obj.TrackCode, out userPassport);

            if (!fetched && !obj.fetchingThumbnail) /*&& (obj.userPassportBytes == null || 
              obj.userPassportBytes.Length == 0))*/
            {
                while (thumbnailThreadCount >= 20)
                {
                    Thread.Sleep(2000);
                }

                thumbnailThreadCount++;

                Thread newT = new Thread(() => { fetchThumbnailsAsync(obj); });
                newT.Start();
            }

            else
            {
                m_log.DebugFormat("Matching {0} to its passport", obj.TrackCode);
                obj.userPassportBytes = userPassport;
            }
        }


    });
        newAppsThread.SetApartmentState(ApartmentState.STA);
        newAppsThread.Start();
        reprintAppsThread.Start();

    }

Вот код поиска:

private void ShowSearchList()
        {
            searchButton.IsEnabled = false;
            searchTextBox.IsEnabled = false;

            string searchTerm = searchTextBox.Text;
            string searchConstraint = ((ComboBoxItem)searchComboBox.SelectedItem).Name;

            IEnumerable<EcofOApplicationObject> searchList;
            List<EcofOApplicationObject> currentList;
            ListView currentListView;
            TabItem currentTab = (TabItem)TabControl.SelectedItem;
            //bool isReprint = false;

            if (DefaultTab.Equals(currentTab))
            {
                currentList = m_AssignmentList;
                currentListView = itemListView;
            }
            else
            {
                currentList = m_ReprintList;
                currentListView = reprintItemListView;
            }

            switch (searchConstraint)
            {
                case "holderNameAddress":
                    searchList = currentList.Where(
                        appli => ((appli.application.Holder.City != null && appli.application.Holder.City.IndexOf(
                            searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) ||
                            (appli.application.Holder.ContactAddress != null && appli.application.Holder.ContactAddress.IndexOf(
                                searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) ||
                                (appli.application.Holder.ContactAddressLga != null && appli.application.Holder.ContactAddressLga.IndexOf(
                                    searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) ||
                                    (appli.application.Holder.ContactAddressState != null &&
                                    appli.application.Holder.ContactAddressState.IndexOf(
                                        searchTerm, StringComparison.OrdinalIgnoreCase) >= 0)));
                    break;
                case "propertyAddress":
                    searchList = currentList.Where(
                        appli => ((appli.application.PropertyLga != null && appli.application.PropertyLga.IndexOf(
                            searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) ||
                            (appli.application.PropertyLocation != null && appli.application.PropertyLocation.IndexOf(
                                searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) ||
                                (appli.application.PropertyLocationDescription != null && appli.application.PropertyLocationDescription.IndexOf(
                                    searchTerm, StringComparison.OrdinalIgnoreCase) >= 0)));
                    break;
                case "propertyUse":
                    searchList = currentList.Where(
                        appli => (appli.ApprovedTypeOfUse != null &&
                            appli.ApprovedTypeOfUse.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "trackCode":
                    // This cannot be null. We check all the same
                    searchList = currentList.Where(
                        appli => (appli.TrackCode != null &&
                            appli.application.TrackCode.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "scheme":
                    searchList = currentList.Where(
                        appli => (appli.Scheme != null &&
                            appli.Scheme.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "surveyPlanNum":
                    searchList = currentList.Where(
                        appli => (appli.application.SurveyPlanNo != null &&
                            appli.application.SurveyPlanNo.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "coordinateOne":
                    searchList = currentList.Where(
                        appli => (appli.application.PropertyCordinate1 != null &&
                            appli.application.PropertyCordinate1.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "coordinateTwo":
                    searchList = currentList.Where(
                        appli => (appli.application.PropertyCordinate2 != null &&
                            appli.application.PropertyCordinate2.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
                case "holderName":
                default:
                    searchList = currentList.Where(
                        appli => (appli.application.Holdernames != null &&
                            appli.application.Holdernames.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0));
                    break;
            }

            currentListView.Items.Clear();
            foreach (EcofOApplicationObject app in searchList)
            {
                currentListView.Items.Add(app);
            }
            refreshDisplay();

            searchButton.IsEnabled = true;
            searchTextBox.IsEnabled = true;
        }

Я читал другие предложения по этой же проблеме, но ни один не кажетсяработать на меня.Как мне решить эту проблему?

1 Ответ

0 голосов
/ 25 сентября 2019

Вы можете создать копию таких элементов, как это:

var itemsCopy = assignmentPage.reprintItemListView.Items.Cast<object>().ToArray();

Однако создавать эту копию в другом потоке, отличном от потока пользовательского интерфейса, по-прежнему небезопасно.Вы все еще можете получить редкие Коллекции были изменены ... исключения.Чтобы сделать его на 100% безопасным, вы должны создать копию, все еще работая в потоке пользовательского интерфейса.Чтобы передать копию в newAppsThread, вы можете использовать ParameterizedThreadStart:

var reprintAppsThread = new Thread(itemsCopy =>

//...

reprintAppsThread.Start(
    assignmentPage.reprintItemListView.Items.Cast<object>().ToArray());
...