相关疑难解决方法(0)

收集被修改; 枚举操作可能无法执行

我无法理解这个错误的底部,因为当附加调试器时,它似乎不会发生.下面是代码.

这是Windows服务中的WCF服务器.每当存在数据事件时,服务就会调用NotifySubscribers方法(以随机间隔,但不常见 - 每天约800次).

当Windows窗体客户端订阅时,订户ID将添加到订阅者字典中,当客户端取消订阅时,将从字典中删除它.客户端取消订阅时(或之后)发生错误.看来,下次调用NotifySubscribers()方法时,foreach()循环失败并显示主题行中的错误.该方法将错误写入应用程序日志,如下面的代码所示.当附加调试器并且客户端取消订阅时,代码执行正常.

你看到这段代码有问题吗?我是否需要使字典线程安全?

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class SubscriptionServer : ISubscriptionServer
{
    private static IDictionary<Guid, Subscriber> subscribers;

    public SubscriptionServer()
    {            
        subscribers = new Dictionary<Guid, Subscriber>();
    }

    public void NotifySubscribers(DataRecord sr)
    {
        foreach(Subscriber s in subscribers.Values)
        {
            try
            {
                s.Callback.SignalData(sr);
            }
            catch (Exception e)
            {
                DCS.WriteToApplicationLog(e.Message, 
                  System.Diagnostics.EventLogEntryType.Error);

                UnsubscribeEvent(s.ClientId);
            }
        }
    }


    public Guid SubscribeEvent(string clientDescription)
    {
        Subscriber subscriber = new Subscriber();
        subscriber.Callback = OperationContext.Current.
                GetCallbackChannel<IDCSCallback>();

        subscribers.Add(subscriber.ClientId, subscriber);

        return subscriber.ClientId;
    }


    public void UnsubscribeEvent(Guid clientId)
    {
        try
        {
            subscribers.Remove(clientId);
        }
        catch(Exception …
Run Code Online (Sandbox Code Playgroud)

c# concurrency wcf dictionary thread-safety

861
推荐指数
10
解决办法
57万
查看次数

ToList() - 它是否创建新列表?

假设我有一堂课

public class MyObject
{
   public int SimpleInt{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我有一个List<MyObject>,然后我ToList()改变其中一个SimpleInt,将我的更改传播回原始列表.换句话说,以下方法的输出是什么?

public void RunChangeList()
{
  var objs = new List<MyObject>(){new MyObject(){SimpleInt=0}};
  var whatInt = ChangeToList(objs );
}
public int ChangeToList(List<MyObject> objects)
{
  var objectList = objects.ToList();
  objectList[0].SimpleInt=5;
  return objects[0].SimpleInt;

}
Run Code Online (Sandbox Code Playgroud)

为什么?

P/S:如果发现它似乎很明显,我很抱歉.但我现在没有编译器...

c# linq

165
推荐指数
7
解决办法
10万
查看次数

收集被修改; 枚举操作可能无法在ArrayList中执行

我正在尝试删除一个项目ArrayList,我得到这个例外:
Collection was modified; enumeration operation may not execute.

有任何想法吗?

c# collections enumeration exception

78
推荐指数
6
解决办法
17万
查看次数

C#List - 循环/迭代时删除项目

假设我有以下代码片段:

var data=new List<string>(){"One","Two","Three"};
for(int i=0 ; i<data.Count ; i++){
  if(data[i]=="One"){
    data.RemoveAt(i);
  }
}
Run Code Online (Sandbox Code Playgroud)

以下代码抛出异常.

我的问题是什么是避免此异常并在循环时删除元素的最佳方法?

.net c# collections list

43
推荐指数
4
解决办法
6万
查看次数

C#从对象列表中删除对象

我有一个对象列表,我试图通过首先检查对象中的属性来删除列表中的特定对象.

最初我使用了a foreach然后意识到你在修改集合时不能使用它,所以我决定使用普通for但是我不知道如何编写能够完成我最初编写的代码.

我如何编写代码来完成我原来的工作?

谢谢

这是我的代码:

    public void DeleteChunk(int ChunkID)
    {
        //foreach (Chunk i in ChunkList)
        //{
        //    if (i.UniqueID == ChunkID)
        //    {
        //        ChunkList.Remove(i);
        //    }
        //}

        //This won't work because here i is just an integer so i.UniqueID won't exist.
        for (int i = 0; i < ChunkList.Capacity; i++)
        {
            if (i.UniqueID == ChunkID)
            {
                ChunkList.Remove(i);
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

c#

20
推荐指数
4
解决办法
11万
查看次数

为什么我没有修改枚举集合时"收集被修改;枚举操作可能无法执行"?

我有两个字符串集合:CollectionA是存储在系统中的对象的StringCollection属性,而CollectionB是在运行时生成的List.如果存在任何差异,CollectionA需要更新以匹配CollectionB.所以我设计了我期望的一个简单的LINQ方法来执行删除.

var strDifferences = CollectionA.Where(foo => !CollectionB.Contains(foo));
foreach (var strVar in strDifferences) { CollectionA.Remove(strVar); }
Run Code Online (Sandbox Code Playgroud)

但我"Collection was modified; enumeration operation may not execute"在strDifferences上收到错误...即使它是一个与被修改的集合中的单独枚举!我最初明确地设计了这个来逃避这个错误,因为我的第一个实现会产生它(因为我在列举CollectionA并且只是删除时!CollectionB.Contains(str)).谁能解释为什么这个枚举失败了?

c# linq enumeration

19
推荐指数
1
解决办法
1万
查看次数

迭代列表并从中删除项目的最佳方法是什么?

我需要迭代List<myObject>并删除回答某个条件的项目.

我看到了这个答案(/sf/answers/110762221/):

使用for循环反向迭代列表:

for (int i = safePendingList.Count - 1; i >= 0; i--)
{
    // some code
    // safePendingList.RemoveAt(i);
}
Run Code Online (Sandbox Code Playgroud)

例:

var list = new List<int>(Enumerable.Range(1, 10));
for (int i = list.Count - 1; i >= 0; i--)
{
    if (list[i] > 5)
      list.RemoveAt(i);
}
list.ForEach(i => Console.WriteLine(i));
Run Code Online (Sandbox Code Playgroud)

但我明白,for比效率较低foreach,

所以我想用后面的如下:

foreach (var item in myList.ToList())
{
    // if certain condition applies:
    myList.Remove(item)
}
Run Code Online (Sandbox Code Playgroud)

一种方法比另一种更好吗?

编辑:

我不想使用RemoveAll(...),因为在条件之前循环中有大量代码.

c# iteration list

16
推荐指数
2
解决办法
6887
查看次数

从'foreach'中有效删除项目

现在,我能想到的最好的是:

bool oneMoreTime = true;
while (oneMoreTime)
{
    ItemType toDelete=null;
    oneMoreTime=false;
    foreach (ItemType item in collection)
    {
        if (ShouldBeDeleted(item))
        {
            toDelete=item;
            break;
        }
    }
    if (toDelete!=null)
    {
        collection.Remove(toDelete);
        oneMoreTime=true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我在这里至少有一个额外的变量,但我把它包括在内以提高算法的可读性.

.net c# collections

14
推荐指数
2
解决办法
3万
查看次数

在迭代时从列表中删除/添加项目

首先,我知道由于显而易见的原因,这不可能开箱即用.

foreach(string item in myListOfStrings) {
    myListOfStrings.Remove(item);
}
Run Code Online (Sandbox Code Playgroud)

上面的剪辑是我见过的最可怕的事情之一.那么,你如何实现呢?您可以使用向后遍历列表for,但我也不喜欢这个解决方案.

我想知道的是:是否有一个方法/扩展从当前列表返回IEnumerable,类似浮动副本?LINQ有很多扩展方法可以做到这一点,但你总是要对它做一些事情,比如过滤(where,take ......).

我期待着这样的事情:

foreach(string item in myListOfStrings.Shadow()) {
   myListOfStrings.Remove(item);
}
Run Code Online (Sandbox Code Playgroud)

其中.Shadow()是:

public static IEnumerable<T> Shadow<T>(this IEnumerable<T> source) {
    return new IEnumerable<T>(source);
    // or return source.Copy()
    // or return source.TakeAll();
}
Run Code Online (Sandbox Code Playgroud)

foreach(ResponseFlags flag in responseFlagsList.Shadow()) {
    switch(flag) {
        case ResponseFlags.Case1:
            ...
        case ResponseFlags.Case2:
            ...
    }
    ...
    this.InvokeSomeVoidEvent(flag)
    responseFlagsList.Remove(flag);
}
Run Code Online (Sandbox Code Playgroud)

这就是我解决它的方式,它就像一个魅力:

public static IEnumerable<T> Shadow<T>(this IEnumerable<T> source) where T: new() {
    foreach(T item in source)
        yield return item;
} …
Run Code Online (Sandbox Code Playgroud)

.net c# extension-methods

10
推荐指数
2
解决办法
3万
查看次数

如何正确地从列表中删除项目

可能重复:
迭代时收集异常并从该集合中删除项目
如何在迭代时从泛型列表中删除元素?
从列表中删除匹配项的更好方法

// tmpClientList is List<Client> type

if (txtboxClientName.Text != "")
    foreach (Client cli in tmpClientList)
        if (cli.Name != txtboxClientName.Text)
            tmpClientList.Remove(cli);
Run Code Online (Sandbox Code Playgroud)

错误:"集合已被修改;枚举操作可能无法执行."

如何以一种简单的方式从列表中删除项目,而不保存这些项目在另一个列表或数组中的索引,并在代码中的其他位置删除它们.尝试了RemoveAt(索引)但它完全相同的情况,修改循环运行时.

c#

6
推荐指数
3
解决办法
2704
查看次数