Não consigo chegar ao fundo desse erro, porque quando o depurador é anexado, ele não parece ocorrer. Abaixo está o código.
Este é um servidor WCF em um serviço do Windows. O método NotifySubscribers é chamado pelo serviço sempre que houver um evento de dados (em intervalos aleatórios, mas não com muita frequência - cerca de 800 vezes por dia).
Quando um cliente Windows Forms se inscreve, o ID do assinante é adicionado ao dicionário de assinantes e, quando o cliente cancela a inscrição, é excluído do dicionário. O erro ocorre quando (ou depois) um cliente cancela a inscrição. Parece que na próxima vez que o método NotifySubscribers () for chamado, o loop foreach () falhará com o erro na linha de assunto. O método grava o erro no log do aplicativo, conforme mostrado no código abaixo. Quando um depurador é anexado e um cliente cancela a inscrição, o código é executado corretamente.
Você vê algum problema com este código? Preciso tornar o dicionário seguro para threads?
[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);
}
}
}