WCF duplex channel Lock ?
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.
Code:
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>(); |
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:
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);
}
} |
Et parfois j'ai une erreur du type "collection was modified ...".
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
Code:
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 |
J'ai cru comprendre qu'en ConcurrencyMode je pouvais mettre la valeur "Multiple", est ce que ça peut m'aider ?
Merci pour votre aide.