2015-04-28 1 views
0

Je suis un débutant en programmation C#.
Quand je lance ce programme, le nom eventhandler - newMessagePublishedEventHandler de la classe MessagePool est toujours nul lors de l'exécution de la fonction OnNewMessagePublished() de la même classe.
Quelqu'un peut-il me dire pourquoi? et aussi comment pourrais-je résoudre cela?Traitement des événements C# - Gestionnaire d'événements reste nul

namespace ConsoleApp 
{ 
public class MessageEventArgs : System.EventArgs 
{ 
    private int publisherId; 
    private string message; 

    public MessageEventArgs(int publisherId, string messageText) 
    { 
     this.publisherId = publisherId; 
     this.message = messageText; 
    } 

    public int PublisherId 
    { 
     get { return publisherId; } 
    } 

    public string Message 
    { 
     get { return message; } 
    } 
} 

public class Publisher 
{ 
    private int publisherId; 

    public Publisher(int publisherId) 
    { 
     this.publisherId = publisherId; 
    } 

    public int PublisherId 
    { 
     get { return publisherId; } 
    } 

    public void Publish(string message) 
    { 
     MessagePool.GetInstance().Publisher_PostMessage(this.publisherId, message); 
     Console.WriteLine("published message - " + message); 
    } 
} 

public class MessagePool 
{ 
    private static MessagePool theOnlyInstanceOfMessageBroker; 

    public static MessagePool GetInstance() 
    { 
     if (theOnlyInstanceOfMessageBroker == null) 
     { 
      return new MessagePool(); 
     } 
     else 
     { 
      return theOnlyInstanceOfMessageBroker; 
     } 
    } 

    private MessagePool() 
    { 
    } 

    private EventHandler newMessagePublishedEventHandler; 

    public event EventHandler NewMessagePublished 
    { 
     add 
     { 
      newMessagePublishedEventHandler += value; 
     } 

     remove 
     { 
      newMessagePublishedEventHandler -= value; 
     } 
    } 

    public void Publisher_PostMessage(int publisherId, string message) 
    { 
     DateTime publishedTime = DateTime.Now; 
     this.OnNewMessagePublished(publisherId, message); 
    } 

    private void OnNewMessagePublished(int publisherId, string message) 
    { 
     MessageEventArgs eventArgs = new MessageEventArgs(publisherId, message); 
     if (newMessagePublishedEventHandler != null) 
     { 
      newMessagePublishedEventHandler(this, eventArgs); 
     } 
    } 
} 

public class Subscriber 
{ 
    private int subscriberId; 

    public Subscriber(int subscriberId) 
    { 
     this.subscriberId = subscriberId; 
     this.SubscribeToMessagebroker(); 
    } 

    public int SubscriberId 
    { 
     get { return subscriberId; } 
    } 

    private void SubscribeToMessagebroker() 
    { 
     MessagePool.GetInstance().NewMessagePublished -= Subscriber_NewMessageArrived; 
     MessagePool.GetInstance().NewMessagePublished += Subscriber_NewMessageArrived; 
    } 

    private void Subscriber_NewMessageArrived(object sender, EventArgs eventArgs) 
    { 
     if (eventArgs != null && eventArgs is MessageEventArgs) 
     { 
      var data = eventArgs as MessageEventArgs; 
      if (data != null) 
       Console.WriteLine("Recieved message : '" + data.Message + "' from " + data.PublisherId); 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Subscriber subscriber = new Subscriber(1); 
     Publisher publisher = new Publisher(1001); 
     publisher.Publish("Hey man.. whats up?"); 
     Console.ReadLine(); 
    } 
} 
} 

Répondre

0

MessagePool n'est pas un bon Singleton, vous êtes toujours retourner une nouvelle MessagePool.

public class MessagePool 
    { 
     private static MessagePool theOnlyInstanceOfMessageBroker; 
     private static object _syncRoot = new object(); 

     public static MessagePool GetInstance() 
     { 
      if (theOnlyInstanceOfMessageBroker == null) 
      { 
       lock(_syncRoot) 
       { 
        if (theOnlyInstanceOfMessageBroker == null) 
         theOnlyInstanceOfMessageBroker = new MessagePool(); 
       } 
      } 

      return theOnlyInstanceOfMessageBroker; 

     } 

     private MessagePool() 
     { 
     } 

//... 
} 
+0

ou simplement 'return theOnlyInstanceOfMessageBroker? (theOnlyInstanceOfMessageBroker = new MessagePool()) ' – stuartd

+0

Oui, cela fonctionnerait, mais parce qu'il est nouveau en C# j'éviterais l'opérateur Coalesce :) –

+0

Votre implémentation de singleton n'est pas non plus thread-safe. – Servy