イベント通信

.NET FrameworkプログラミングTips

オブジェクトが生成したイベントを、他の場所で拾う仕組みを解明する。 具体的には、ViewにEventHandlerを記述し、WorkerObjectに登録することによって、 そこで発生したEventがViewに送られるプログラムを構築する。 また、ユーザ定義のメッセージとしてXMLを内包できるようにEventを拡張する。

XMLEventの設計

XMLメッセージを伝達するEvent (XMLEvent)の設計を行う。

Event機構を考える上で重要となるのはEventArgs(イベントオブジェクト)とEventHandlerである。 XMLEventの場合、これらの名前にはXMLEventArgs, XMLEventHandlerというように、"XML"を頭につけることが.NETでは推奨されている。

XMLEventArgs

XMLEventArgsは実際にXMLEventとして伝送されるオブジェクトである。 ここにString*型のXmlMessageを含ませるには、次のように記述すればいい。

__gc class XMLEventArgs : EventArgs{
private:
   String* m_XmlMessage;
public:
   XmlEventArgs(String* xml_message) : EventArgs(){
      m_XmlMessage=xml_message;
   }

   __property get_XmlMessage(){
      return m_XmlMessage;
   }
};

XMLEventHandler

XMLEventHandlerは、まずハンドラとしての関数型定義を行う必要がある。

__delegate void XMLEventHandler(Object* sender,XMLEventArgs* e);

これは、XMLEventHandlerの型を定義している。 この型を使うことで、Eventの送信側と受信側を接続することが可能になる。


EventArgsの受信

View内にXMLEventHandlerを作成した例は次のとおりである。

__gc class XmlReceiverView{ 
・・・・・・省略・・・・・・・
private: 
  void xml_received(Object* sender,XMLEventArgs* e){
    //  XMLEventの処理
    String* xml=e->XmlMessage;
    MessageBox::Show(xml);
  }
・・・・・・省略・・・・・・・
}

xml_receivedが実際にイベントを処理するメソッド。 XMLEventHandlerと同じ型をしている。

以上で、Event受信側の準備は整う。


EventArgsの送信

生成されたXMLメッセージをXMLEventArgsに乗せて送信する場合の記述例。

__gc class XmlSenderWorkerObject{
protected:
   XMLEventHandler* m_XmlEventHandler;

public:
・・・・・・省略・・・・・・・
      String* xml=・・・;
      m_XmlEventHandler->Invoke(this,new XMLEventArgs(xml));   
・・・・・・省略・・・・・・・
};

HandlerのInvokeメソッドでXMLEventArgsが送信される。 ここで、m_XmlEventHandlerはXmlReceiverViewのxml_receivedメソッドを指定している必要がある。


EventHandlerの登録

Event通信を行うためには上記の準備がすべて整った上で、送信側に受信側のEventHandlerを登録する必要がある。 そのためには、まず次のようにXmlSenderWorkerObjectクラスに登録のための仕組みを用意しなければならない。

void SetXmlEventHandler(XMLEventHandler* handler){
  m_XmlEventHandler=handler;
}

受信側から送信側にxml_receivedを登録するにはXmlReceivedViewクラス内に次のように記述する。

// m_Worker points to an instance of XmlSenderWorkerObject
m_Worker->SetXmlEventHandler(new XMLEventHandler(this,xml_received));

以上で、XMLEventHandlerはXmlSenderWorkerObjectのインスタンスに登録される。


全体のスクリプト

イベントの設計、受信側の実装、送信側の実装、イベントハンドラの登録をすべてまとめると次のようになる。 実際には、イベントはMultiThread環境下でよく用いられるため、これらのクラスにはスレッド関連の処理も付随するのが普通である。

namespace XmlEvent{

// XMLEventArgsの定義
public __gc class XMLEventArgs : EventArgs{
private:
   String* m_XmlMessage;
public:
   XmlEventArgs(String* xml_message) : EventArgs(){
      m_XmlMessage=xml_message;
   }

   __property get_XmlMessage(){
      return m_XmlMessage;
   }
};

// XMLEventHandlerの型定義
public __delegate void XMLEventHandler(Object* sender,XMLEventArgs* e);


// WorkerObject
public __gc class XmlSenderWorkerObject{
protected:
   XMLEventHandler* m_XmlEventHandler;

public
   XmlSenderWorkerObject(){}

public:
   // イベントの登録
   void SetXmlEventHandler(XMLEventHandler* handler){
      m_XmlEventHandler=handler;
   }

・・・・・・省略・・・・・・・
public:
   void MainThread(){
      ・・・・・・省略・・・・・・・
      String* xml=・・・;
      // イベントの送信
      m_XmlEventHandler->Invoke(this,new XMLEventArgs(xml));
      ・・・・・・省略・・・・・・・
   }
・・・・・・省略・・・・・・・
};

// View
public __gc class XmlReceiverView{ 
・・・・・・省略・・・・・・・
private:
   XmlSenderWorkerObject* m_Worker;
  
public:
   XmlReceiverView(){
      m_Worker=new XmlSenderWorkerObject();
      // イベントハンドラの登録
      m_Worker->SetXmlEventHandler(new XMLEventHandler(this,xml_received));
   }
  
private: 
   // イベントハンドラ
   void xml_received(Object* sender,XMLEventArgs* e){
     //  XMLEventの処理
     String* xml=e->XmlMessage;
     MessageBox::Show(xml);
   }
・・・・・・省略・・・・・・・
};

}
Copyright © 2004-2006 Multisoft-lab   All rights reserved.