2017-03-10 4 views
1

J'ai un service WAS configuré sur Windows 10 IIS 1511. J'ai créé une application de test simple pour trier toutes les zones problématiques avant de commencer mon projet actuall. J'ai mon service configuré avec plusieurs simultané et Instance à single. J'ai un dictionnaire concurrent pour gérer la concurrence. Je fais 2 appels au service avec 2 objets proxy différents pour m'abonner à mon observateur/sujet. la méthode subscribe ajoute des abonnés au dictionnaire. après le deuxième appel proxy, il y a seulement un élément dans le dictionnaire et je m'attendais à 2. Donc, il semble que mon service ne persiste pas mes changements dans le dictionnaire. Cependant, si j'utilise l'opération Hello, qui augmente simplement un compteur (type de valeur), le compte est 2 après le second appel. Voici mon code de console client:Le service WCF n'est pas permanent Types de référence en service

static void Main(string[] args) 
    { 
     string personErnie = "Ernie"; 
     string personAlvin = "James"; 

     //using (PersonTracker.PersonTrackerClient personTracker1 = 
     // new PersonTracker.PersonTrackerClient("PersonTrackerPipeEndPoint")) 
     //using (PersonTracker.PersonTrackerClient personTracker2 = 
     // new PersonTracker.PersonTrackerClient("PersonTrackerPipeEndPoint")) 
     using (PersonTracker.PersonTrackerClient personTracker1 = 
      new PersonTracker.PersonTrackerClient("PersonTrackerHTTPEndPoint")) 
     using (PersonTracker.PersonTrackerClient personTracker2 = 
       new PersonTracker.PersonTrackerClient("PersonTrackerHTTPEndPoint")) 
     { 

      string h1 = personTracker1.Hello(personErnie); //Output: Hello Ernie, Seems like you using the http protocol, count = 1 
      string h2 = personTracker1.Hello(personAlvin); //Output: Hello James, Seems like you using the http protocol, count = 2 

      PersonObserver personObserverErnie = new PersonObserver(personErnie); 
      object disposeObserverErnie = personTracker1.Subscribe(personObserverErnie); // Dictionary Count = 1 

      PersonObserver personObserverJames = new PersonObserver(personAlvin); 
      object disposeObserverJames = personTracker2.Subscribe(personObserverJames); // Dictionary Count = 1 
     } 
    } 

Voici ma classe de service:

[ServiceBehavior(
     ConcurrencyMode = ConcurrencyMode.Multiple, 
     InstanceContextMode =InstanceContextMode.Single)] 
public class PersonTracker : IPersonTracker 
{ 

    public static ConcurrentDictionary<string, PersonObserver> observers = null; 
    int Counter; 

    public string Hello(string name) 
    { 
     string protocol = OperationContext.Current.Channel.LocalAddress.Uri.Scheme; 
     return string.Format("Hello {0}, Seems like you using the {1} protocol, count = {2}",name, protocol,Counter++); 
    } 

    public UnsibscribePerson Subscribe(PersonObserver observer) 
    { 
     if (observers == null) 
     { 
      observers = new ConcurrentDictionary<string, PersonObserver>(); 
     } 
     if (!observers.ContainsKey(observer.Name)) 
     { 
      observers.AddOrUpdate(observer.Name, observer, (key, oldValue) => { return new PersonObserver(oldValue.Name); }); 
     } 

     return new UnsibscribePerson(observers, observer); 
    } 
} 

Voici mon interface du contrat:

[ServiceContract(SessionMode = SessionMode.Required)] 
public interface IPersonTracker 
{ 
    [OperationContract] 
    string Hello(string name); 

    [OperationContract] 
    UnsibscribePerson Subscribe(PersonObserver observer); 
} 

La classe de désabonnement est une classe extension du IDisposable pour le client se désinscrit une fois que j'ai trié (Pipes).

Question: Pourquoi le dictionnaire persiste pas mes observateurs mais j'ajouter pour le compteur, il ne ...

MISE À JOUR:

Ainsi, tout en supprimant l'objet UnsibscribePerson dans le type de retour de mon opération Abonnez-vous J'ai résolu mon problème, mais je dois retourner cet objet. Est-ce quelque chose à faire avec mon objet UnsibscribePerson, voici mes modifications apportées et mon objet UnsibscribePerson:

[ServiceContract] 
public interface IPersonTracker 
{ 
    [OperationContract] 
    string Hello(string name); 

    [OperationContract(IsInitiating = true)] 
    void Subscribe(PersonObserver observer); 
} 

Et voici mon objet UnsibscribePerson:

[DataContract(IsReference = true)] 
public class UnsibscribePerson : IDisposable 
{ 
    [DataMember(EmitDefaultValue = false)] 
    private PersonObserver observer; 

    [DataMember(EmitDefaultValue = false)] 
    private ConcurrentDictionary<string, PersonObserver> persons; 

    public UnsibscribePerson(ConcurrentDictionary<string, PersonObserver> persons, PersonObserver observer) 
    { 
     this.persons = persons; 
     this.observer = observer; 
    } 

    public void Dispose() 
    { 
     if (observer != null && persons.ContainsKey(observer.Name)) 
     { 
      PersonObserver person = null; 

      persons.TryRemove(observer.Name, out person); 
     } 
    } 
} 

Je change également le type de retour à une valeur tapez (en retournant le compte de la liste) et j'ai obtenu les résultats (compte de 1 et 2). Cela semble toujours être lié aux types de référence et aux types de valeur?

Répondre

0

Ceci est gênant :) Ma méthode de la classe Éliminez UnsibscribePerson est appelée qui supprime mon abonné droit après avoir été ajouté ....

solution Donc pour moi était de ne pas mettre en œuvre l'interface IDisposbale