2

循环浏览集合时出现错误。我不会在任何时候更改列表,但它给了我以下“集合已修改;枚举操作可能无法执行。以下代码显示了我拥有此 Parallel.Foreach 的方法。

public void DownloadImages()
        {
            IList<Vehicle> vehicles = _repository.Retrieve().ToList();
            Parallel.ForEach(vehicles, vehicle =>
            {
                IList<VehiclePhoto> vehiclePhotos =
                    vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).ToList();
                if (vehiclePhotos.Count > 0)
                {
                    Parallel.ForEach(vehiclePhotos, photo =>
                    {
                        using (var client = new WebClient())
                        {
                            try
                            {
                                string fileName = Guid.NewGuid() + ".png";
                                string filePath = _imagePath + "\\" + fileName;
                                client.DownloadFile(photo.ImageUrl, filePath);
                                photo.FileName = fileName;
                                photo.ImageStatus = ImageStatus.Active;
                            }
                            catch (Exception)
                            {
                            }
                        }
                    });

                    _repository.Save(vehicle);
                }
            });
        }

调用 _repository.Save(vehicle) 时会发生这种情况。以下代码将显示保存更改方法。base.SaveChanges(); 是引发错误的地方。

public override int SaveChanges()
        {
            DateTime nowAuditDate = DateTime.Now;
            IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry<DomainEntity>> changeSet = ChangeTracker.Entries<DomainEntity>();
            if (changeSet != null)
            {
                foreach (System.Data.Entity.Infrastructure.DbEntityEntry<DomainEntity> entry in changeSet)
                {
                    switch (entry.State)
                    {
                        case EntityState.Added:
                            entry.Entity.Created = nowAuditDate;
                            entry.Entity.Modified = nowAuditDate;
                            break;
                        case EntityState.Modified:
                            entry.Entity.Modified = nowAuditDate;
                            break;
                    }
                }
            }

            return base.SaveChanges();
        }

对此有什么想法吗?

已编辑: 我试图修复上述错误并在 DownloadImages 方法中更改了几行代码。这些变化如下:

代替

IList<Vehicle> vehicles = _repository.Retrieve().ToList(); 

我用了 var

var vehicles = _repository.Retrieve().AsParallel(); 

代替

IList<VehiclePhoto> vehiclePhotos =
                        vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).ToList();

我用了 var

var  vehiclePhotos =
                            vehicle.VehiclePhotos.Where(x => x.ImageStatus == ImageStatus.Inactive).AsParallel();

当我尝试再次运行代码时。它给了我一个不同的错误:错误如下:

在标题中它说

System.Data.Entity.Infrastructure.DbUpdateException

但是在innerException

System.Data.Entity.Core.UpdateException

当分配给命令的连接处于挂起的本地事务中时,ExecuteNonQuery 要求该命令具有事务。该命令的 Transaction 属性尚未初始化。

4

1 回答 1

1

发生这种情况是因为您正在迭代vehicles并且循环内的代码正在更改 enumeration 的元素vehicles。此外,循环vehiclePhotos并更改它的元素。

我通常通过使用显式for循环来解决这个问题,即:

for(var i = 0; i < vehicles.Count; i++)
{
    var vehicle = vehicles.ElementAt(i);

    // process vehicle
}

但是,如果您需要使用Parallel.ForEach,您可以尝试创建一个长度为 的整数数组vehicles.Count,对其进行迭代并将其用作 的索引vehicles

于 2014-03-14T16:45:20.363 回答