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.
(这是Windows服务中的WCF服务器。)
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). (每当有数据事件时,服务就会调用NotifySubscribers方法(以随机间隔,但不是很频繁-每天大约800次)。)
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.
(Windows Forms客户端进行预订时,订户ID被添加到订户字典中,而当客户端取消订阅时,将从该字典中删除它。)
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. (看来,下次调用NotifySubscribers()方法时,foreach()循环因主题行中的错误而失败。)
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);
}
}
}
ask by cdonner translate from so 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…