收集被修改;枚举操作可能无法执行 [英] Collection was modified; enumeration operation may not execute

查看:151
本文介绍了收集被修改;枚举操作可能无法执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法得到这个错误的底部,因为当调试器附加,它似乎没有发生。下面是代码。



这是Windows服务中的WCF服务器。



当Windows窗体中有NotifySubscribers时,只要有数据事件,就会调用NotifySubscribers方法(以随机的时间间隔,但不是非常频繁 - 客户端订阅,订阅者ID被添加到订阅者字典,并且当客户端取消订阅时,它从字典中删除。在客户端取消订阅时(或之后)发生错误。看来下次调用NotifySubscribers()方法时,foreach()循环将失败,并显示主题行中的错误。该方法将错误写入应用程序日志,如下面的代码所示。当调试器附加并且客户端取消订阅时,代码执行得很好。



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

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

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

public void NotifySubscribers(DataRecord sr)
{
foreach(subscriber.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 e)
{
System.Diagnostics.Debug.WriteLine(Unsubscribe Error+
e.Message);
}
}
}


解决方案>

可能发生的是,SignalData在循环期间间接地改变用户字典,并导致该消息。您可以通过更改


验证这一点。
> foreach(订阅者在订阅者值中)

  foreach Values.ToList())

如果我是对的,问题会消失


I can't get to the bottom of this error, because when the debugger is attached, it does not seem to occur. Below is the code.

This is a WCF server in a Windows service. The method NotifySubscribers is called by the service whenever there is a data event (at random intervals, but not very often - about 800 times per day).

When a Windows Forms client subscribes, the subscriber ID is added to the subscribers dictionary, and when the client unsubscribes, it is deleted from the dictionary. The error happens when (or after) a client unsubscribes. It appears that the next time the NotifySubscribers() method is called, the foreach() loop fails with the error in the subject line. The method writes the error into the application log as shown in the code below. When a debugger is attached and a client unsubscribes, the code executes fine.

Do you see a problem with this code? Do I need to make the dictionary thread-safe?

[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 e)
        {
            System.Diagnostics.Debug.WriteLine("Unsubscribe Error " + 
                    e.Message);
        }
    }
}

解决方案

What's likely happening is that SignalData is indirectly changing the subscribers dictionary under the hood during the loop and leading to that message. You can verify this by changing

foreach(Subscriber s in subscribers.Values)

To

foreach(Subscriber s in subscribers.Values.ToList())

If I'm right, the problem will dissapear

这篇关于收集被修改;枚举操作可能无法执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆