Bonjour,
J'ai créé un service WCF qui permet de lancer un ensemble de service.
Ce serveur WCF contient plusieurs listes génériques de type List<myObject>, dont une liste qui contient la liste des utilisateurs actuellement connectés.
Le service fait des callback en temps réel à tous mes utilisateurs connectés en fonction des événements qui se produisent sur mon service WCF.
Lorsqu'un utilisateur se connecte ou se déconnecte je mets à jour cette liste en faisant un "Add" ou un "Remove", voir exemple ci-dessous.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 /// <summary> /// Liste des utilisateur qui se sont authentifiés sur le serveur /// </summary> private static readonly List<ICallbackScheduler> subscribers = new List<ICallbackScheduler>();
Et parfois j'ai une erreur du type "collection was modified ...".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 /// <summary> /// Méthode permettant de s'inscrire sur l'ordonnanceur en tant qu'utilisateur /// </summary> public void suscribeUser(UserAcompt userAcompt) { try { if (userAcompt == null) throw new NullReferenceException("Le profil utilisateur ne peut être NULL"); // -- Ajout de l'utilisateur à la liste // -- des utilisateurs connectés // ------------------------------------ if (UserAcomptCollection.searchById(this.listUsers, UserAcompt.LIdUser) == null) this.listUsers.Add(UserAcompt); // -- Création du canal callback permettant de // -- s'assurer de la connexion client / scheduler // -------------------------------------------- ICallbackScheduler callbackScheduler = OperationContext.Current.GetCallbackChannel<ICallbackScheduler>(); ICommunicationObject obj = (ICommunicationObject)callbackScheduler; obj.Closed += obj_Closed; obj.Faulted += obj_Closed; if (!subscribers.Contains(callbackScheduler)) subscribers.Add(callbackScheduler); // -- Appel de la méthode callback // -- sur les utilisateurs connectés // --------------------------------- foreach (ICallbackScheduler ic in subscribers.ToList()) ic.userConnected(userAcompt); } catch (NullReferenceException) { } catch (Exception ex) { adviseClientsAboutSchedulerException("Scheduler.suscribeUser : " + ex.Message); } }
J'imagine qu'il arrive qu'un utilisateur se connecte ou déconnecte alors que je suis en train de diffuser de l'information à toute ma liste en bouclant sur cette liste.
Comment est ce que je peux sécuriser cela ? Par un lock ?
Mon service est configuré de cette manière
J'ai cru comprendre qu'en ConcurrencyMode je pouvais mettre la valeur "Multiple", est ce que ça peut m'aider ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 /// <summary> /// Service proposés au client sur l'ordonnanceur /// </summary> [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)] public class GTMScheduler : IGTMScheduler
Merci pour votre aide.
Partager