2017-02-09 1 views
0

J'ai une classe singleton où une liste d'objets est placée. J'ai donc une classe qui définit les éléments de cette liste. Ensuite, j'ai une autre classe qui obtient la liste des objets de cette classe singleton. Mon problème est quand je reçois un message de nservicebus et obtiens la liste de la classe de singleton, il y a des fois que la liste ne contient aucun objet. Et il y a des fois que les objets existent. Donc, ce que j'ai fait c'est que chaque fois que j'obtiens l'instance singleton, j'exécute 'GetHashCode' et je confirme qu'il y a 2 instances différentes de la classe Singleton. Qu'ai-je mal implémenté avec mon code?Une application Web a 2 instances de la classe Singleton

public class SingletonClass 
{ 
    private static readonly object _lockObj = new object(); 
    private static readonly object _lockObjList = new object(); 

    static SingletonClass _singletonClass; 

    private static List<object> _objList; 


    private SingletonClass() 
    { 

    } 

    public static SingletonClass Instance 
    { 
     get 
     { 
      lock(_lockObj) 
      { 
       if (null == _singletonClass) 
       { 
        _singletonClass= new SingletonClass(); 
        _objList = new List<object>(); 
       } 
       return _singletonClass; 
      } 
     } 
    } 

    public List<obj> GetList() 
    { 
     lock(_lockObjList) 
     { 
      return _objList; 
     } 
    } 

    public void UpdateProgress(int index, double value) 
    { 
     lock(_lockObjList) 
     { 
      _objList[index].Progress = value; 
     } 
    } 


    public void SetList(List<obj> objs) 
    { 
     lock(_lockObjList) 
     { 
      _objList = objs; 
     } 
    } 
} 
public class MessageHandler : HubInvoker<MessageHub> 
{ 

    public MessageHandler() {} 

    public void OnReceiveMessage(object sender, MessageArgs args) 
    { 
     var list = SingletonClass.Instance.GetList(); 
     if(list != null){ 
      var i = 0; 
      for(; i < list.Length && list[i].Id == args.Id; i++); 

      if(i < list.Length) 
      { 
       SingletonClass.Instance.UpdateProgress(i, args.Progress); 
      } 
     } 
    } 
} 
public class ObjController 
{ 
    public ObjController() {} 

    public void SetList(List<obj> objs) 
    { 
     SingletonClass.Instance.SetList(objs); 
    } 
} 

ÉDITÉE

J'ai ajouté quelques codes ci-dessus pour plus d'informations de ma mise en œuvre.

+0

je ne serais probablement aller juste pour une approche '' Lazy . Ne faites pas de la classe une classe singleton, il suffit de stocker sa valeur dans un champ statique Lazy ' –

+0

Pourquoi avez-vous besoin de cette liste pour être statique singleton en premier lieu de toute façon? –

+0

@ CallumLinington La liste est modifiée dans l'application de manière asynchrone. Plusieurs classes accéder et modifier la liste – chary

Répondre

0

Vous devrez mettre en œuvre un double verrouillage, voir here et, selon votre configuration, un mot clé volatile. Voir ci-dessous le code:

public static SingletonClass Instance 
{ 
    get 
    { 
     if (null == _singletonClass) 
     { 
      lock (_lockObj) 
      { 
       if (null == _singletonClass) 
       { 
        _singletonClass = new SingletonClass(); 
        _objList = new List<object>(); 
       } 
       return _singletonClass; 
      } 
     } 
    } 
} 
+0

J'ai essayé l'approche de double verrouillage mais ayant toujours 2 instances différentes – chary

+0

Will article] (https://docs.particular.net/nservicebus/containers/#dependency-lifecycle-singleinstance) aide? –