【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
我无法弄清此错误的原因,因为在连接调试器时,似乎没有发生此错误。 下面是代码。
这是Windows服务中的WCF服务器。 每当有数据事件时,服务就会调用NotifySubscribers方法(以随机间隔,但不是很频繁-每天大约800次)。
Windows Forms客户端进行预订时,订户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 e)
{
System.Diagnostics.Debug.WriteLine("Unsubscribe Error " +
e.Message);
}
}
}
#1楼
实际上,在我看来,问题似乎在于您正在从列表中删除元素,并希望继续读取列表,就好像什么都没发生一样。
您真正需要做的是从头开始,然后再回到头。 即使您从列表中删除了元素,您也可以继续阅读它。
#2楼
您还可以锁定您的订户字典,以防止其在循环时被修改:
lock (subscribers)
{
foreach (var subscriber in subscribers)
{
//do something
}
}
#3楼
您可以将订户字典对象复制到相同类型的临时字典对象,然后使用foreach循环迭代该临时字典对象。
#4楼
因此,解决此问题的另一种方法是代替删除元素来创建新字典,而仅添加您不想删除的元素,然后用新字典替换原始字典。 我认为这不是效率问题,因为它不会增加您遍历结构的次数。
#5楼
我有同样的问题,当我使用for
循环而不是foreach
时,它就解决了。
// foreach (var item in itemsToBeLast)
for (int i = 0; i < itemsToBeLast.Count; i++)
{
var matchingItem = itemsToBeLast.FirstOrDefault(item => item.Detach);
if (matchingItem != null)
{
itemsToBeLast.Remove(matchingItem);
continue;
}
allItems.Add(itemsToBeLast[i]);// (attachDetachItem);
}
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3143944