2009-11-26 4 views
1

Afin de comprendre le moniteur, j'ai implémenté le code suivant. Mais je ne suis pas sûr si le code est Thread Safe.C# 3.0 - Application de Monitor -Suggestions

namespace MonitorExample 
{ 
    public delegate void WaterLevelInformer(object sender,WaterLevelArgs e); 

    class WaterLevelListener 
    { 
     //listener will print information 
     // when WaterTank is reaching its empty level or full 
     public void ShowResult(object sender, WaterLevelArgs e) 
     { 
      Console.WriteLine("Water Level is :{0}", e.Level); 
     } 
    } 

    class WaterTank 
    { 
     //starting level is empty 
     static int level=0; 
     //capacity of the WaterTank is 2000 liters 
     const int capacity = 2000; 
     private WaterLevelListener lst = new WaterLevelListener(); 

     public event WaterLevelInformer levelHandler; 

     public WaterTank(WaterLevelListener lstn) 
     { 
      this.lst = lstn; 
      this.levelHandler +=new WaterLevelInformer(lst.ShowResult); 
     } 

     public void FillWater() 
     { 
      lock (this) 
      { 
       if (level >= capacity) 
       { 
        Monitor.Wait(this); 
       } 
       Console.WriteLine("....WaterTank is gettig filled..."); 
       for (int i = 100; i <= 2000; i+=100) 
       { 
        Console.WriteLine("Current Water Level {0}", i); 
        level = i; 
        Thread.Sleep(1000); 
        if (i == 1700) 
        { 
         WaterLevelInformation(level); 
         Thread.Sleep(1000); 
        } 
       } 

       Monitor.Pulse(this); 
      } 
     } 

     public void ConsumeWater() 
     { 
      lock (this) 
      { 
       if (level<=0) 
       { 
        Monitor.Wait(this); 
       } 
       Console.WriteLine("...Water is being consumed...."); 
       for (int i =2000; i >= 0; i -= 100) 
       { 
        Console.WriteLine("Current Water Level {0}", i); 
        Thread.Sleep(1000); 
        level = i; 
        if (i == 100) 
        { 
         WaterLevelInformation(i); 
         Thread.Sleep(1000); 
        } 
       } 

       Monitor.Pulse(this); 
      } 
     } 

     //WaterLevelInformation is used to raise the event 
     // When WaterTank reaching its empty level 
     //or WaterTank is full 
     public void WaterLevelInformation(int i) 
     { 
      if (levelHandler != null) 
      { 
       WaterLevelArgs waterArgs=new WaterLevelArgs(i); 
       levelHandler(this,waterArgs); 
      } 
     } 
    } 

    // WaterLevelArgs class stores the level of 
    // the water 
    public class WaterLevelArgs : EventArgs 
    { 
     public int Level 
     { 
      get; 
      set; 
     } 
     public WaterLevelArgs(int level) 
     { 
      Level = level; 
     } 
    } 

    class WaterLevelSimulator 
    { 

     static void Main() 
     { 
      WaterLevelListener lst = new WaterLevelListener(); 
      WaterTank tnk = new WaterTank(lst); 
      Thread thd1 = new Thread(new ThreadStart(tnk.ConsumeWater)); 
      Thread thd2 = new Thread(new ThreadStart(tnk.FillWater)); 
      thd1.Start(); 
      thd2.Start(); 
      Console.ReadKey(); 
     } 
    } 

} 

Questions:

1) Le code ci-dessus est thread-safe?

2) Comme C# 2.0 et 3.0 ont introduit l'action <>, Prédire <>, lambdas comment puis-je améliorer mon code?

3) Quel est le modèle le mieux puis-je suivre pour utiliser l'éditeur, modèle d'observateur, je veux dire devrais-je besoin de concevoir la classe distincte pour (i) EventArgs personnalisés (ii) Les auditeurs (iii) les éditeurs (iv) éditeur de liens - (auditeurs de liens, éditeurs, EventArgs personnalisés)?

Répondre

1

En utilisant lock(this) (également Monitor.Wait(this)) n'est pas recommandé par Microsoft (voir MSDN on lock-Keyword).

Vous devriez utiliser un objet de verrouillage séparé, comme une variable string ou autre chose qui est un objet - cela ne fonctionnera pas pour les types simples comme int ou quelque chose.

0

Est-ce que c'est un devoir? Quoi qu'il en soit ...

1) Après un coup d'œil rapide, le code me semble bien sûr, mais si fortement synchronisé que les threads n'effectuent aucun travail simultanément. Par conséquent, pour ce code, vous pourriez tout aussi bien avoir un thread avec une boucle.

2) Ne vous inquiétez pas à ce sujet maintenant, une véritable amélioration ne vient pas seulement de la syntaxe (et dans ce cas, c'est principalement ce que ces constructions vous apporteraient).

3) Ce n'est pas clair pour moi ce dont vous avez besoin là-bas.

+0

Lorsque vous pensez qu'une personne souhaite clarifier quelque chose est à la maison, alors ce sont les devoirs. – user215675