Nie mogę dotrzeć do sedna tego błędu, ponieważ kiedy dołączony jest debugger, wydaje się, że nie występuje. Poniżej znajduje się kod.
To jest serwer WCF w usłudze Windows. Metoda NotifySubscribers jest wywoływana przez usługę za każdym razem, gdy występuje zdarzenie danych (w przypadkowych odstępach czasu, ale niezbyt często - około 800 razy dziennie).
Gdy klient Windows Forms subskrybuje, identyfikator subskrybenta jest dodawany do słownika subskrybentów, a gdy klient anuluje subskrypcję, jest usuwany ze słownika. Błąd występuje, gdy klient anuluje subskrypcję (lub później). Wygląda na to, że przy następnym wywołaniu metody NotifySubscribers () pętla foreach () zawiedzie z błędem w temacie. Metoda zapisuje błąd w dzienniku aplikacji, jak pokazano w poniższym kodzie. Gdy podłączony jest debuger, a klient anuluje subskrypcję, kod działa poprawnie.
Czy widzisz problem z tym kodem? Czy muszę zapewnić bezpieczeństwo wątku w słowniku?
[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);
}
}
}