我无法理解这个错误的底部,因为当附加调试器时,它似乎不会发生.下面是代码.
这是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) 假设我有一堂课
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:如果发现它似乎很明显,我很抱歉.但我现在没有编译器...
我正在尝试删除一个项目ArrayList,我得到这个例外:
Collection was modified; enumeration operation may not execute.
有任何想法吗?
假设我有以下代码片段:
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)
以下代码抛出异常.
我的问题是什么是避免此异常并在循环时删除元素的最佳方法?
我有一个对象列表,我试图通过首先检查对象中的属性来删除列表中的特定对象.
最初我使用了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) 我有两个字符串集合: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)).谁能解释为什么这个枚举失败了?
我需要迭代List<myObject>并删除回答某个条件的项目.
我看到了这个答案(/sf/answers/110762221/):
使用for循环反向迭代列表:
Run Code Online (Sandbox Code Playgroud)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));
但我明白,for比效率较低foreach,
所以我想用后面的如下:
foreach (var item in myList.ToList())
{
// if certain condition applies:
myList.Remove(item)
}
Run Code Online (Sandbox Code Playgroud)
一种方法比另一种更好吗?
编辑:
我不想使用RemoveAll(...),因为在条件之前循环中有大量代码.
现在,我能想到的最好的是:
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)
我知道我在这里至少有一个额外的变量,但我把它包括在内以提高算法的可读性.
首先,我知道由于显而易见的原因,这不可能开箱即用.
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) // 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# ×10
.net ×3
collections ×3
enumeration ×2
linq ×2
list ×2
concurrency ×1
dictionary ×1
exception ×1
iteration ×1
wcf ×1