0

我在线程中有一个方法可以拉取用户图像,并将图像绑定到 ItemCollection 列表。在提取图像时,我希望能够搜索列表。我不断收到此错误,Collection 已修改;枚举操作可能无法执行。这是图像拉取代码:

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

我已经阅读了关于同一问题的其他建议,但似乎没有一个对我有用。我该如何解决这个问题?

4

1 回答 1

0

您可以像这样创建项目的副本:

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

尽管在与 UI 线程不同的线程中创建此副本仍然不安全。你可能仍然会得到一些罕见的Collection 被修改...例外。为了使其 100% 安全,您必须在仍在 UI 线程中运行时创建副本。要传递副本,newAppsThread您可以使用ParameterizedThreadStart

var reprintAppsThread = new Thread(itemsCopy =>

//...

reprintAppsThread.Start(
    assignmentPage.reprintItemListView.Items.Cast<object>().ToArray());
于 2019-09-25T16:40:36.980 回答