2009年2月16日 星期一

MSMQ


MSMQ
::Microsoft Message Queue(訊息駐列)


啟動MSMQ
::


C#使用方式
傳訊
1.建立要傳送資料
System.Messaging.Message hashtable_Msg = new System.Messaging.Message(strHashtable, new System.Messaging.BinaryMessageFormatter());
2.指定MSMQ Channel 或建立MSMQ Channel
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");

3.傳送到Message Queue
msgQ.Send(hashtable_Msg);

收訊
1.指定MSMQ Channel 或建立MSMQ Channel
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");

2.設定這個Message Queue資訊格式
msgQ.Formatter = new System.Messaging.BinaryMessageFormatter();
3.接收Message
strHashtable = ((System.Collections.Hashtable)msgQ.Receive().Body);

//-------------- 範例 ---------------//
傳訊
Hashtable strHashtable = new Hashtable();
double key = 0;
string valueString = "Dispose";
strHashtable.Add(key, valueString);
// 傳送Hashtable 格式資料時,需要使用BinaryMessageFormatter方式傳送
System.Messaging.Message hashtable_Msg = new System.Messaging.Message
(strHashtable, new System.Messaging.BinaryMessageFormatter());


System.Messaging.MessageQueue msgQ;
// 確認是否有用來傳送的Channel存在,在這 Channel 名稱由使用者定為MDSQueue
if (System.Messaging.MessageQueue.Exists(@".\Private$\MDSQueue"))
{
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
}
else
{
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
}

// 使用Message Queue 的 Object 來傳送訊息
try
{
msgQ.Send(hashtable_Msg);
// 中斷在接收訊息的Message Queue Thread
ThreadAll[0].Interrupt();
}
catch
{
}

收訊
public void ListenMDSQueue()
{
// Create MessageQueue Object。
System.Messaging.MessageQueue msgQ;
// 確認是否有用來傳送的Channel存在,在這 Channel 名稱由使用者定為MDSQueue

if (System.Messaging.MessageQueue.Exists(@".\Private$\MDSQueue"))
{
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
}
else
{
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
}


// Always listen MDS Queue until interrupt。
while (true)
{
try
{
// 使用Thread時interrup機制在MessageQueue Receive時無法中斷
// 需要MessageQueue收到訊息釋放Thread的控制,interrup才能有作用
// 可以使用 Sleep機制在進入Receive時,先確定是否有Interrup發生.

System.Threading.Thread.Sleep(80);


System.String ContextString = "";
System.Collections.Hashtable strHashtable = new System.Collections.Hashtable();
System.Object o = new System.Object();
System.Type[] arrTypes = new System.Type[2];
arrTypes[0] = strHashtable.GetType();
arrTypes[1] = o.GetType();
// Message 如果沒有定義格式.預設是使用XmlMessageFormatter
// 這個格式無法存放Hashtable型態的訊息,所以改用BinaryMessageFormatter
// msgQ.Formatter = new System.Messaging.XmlMessageFormatter(arrTypes);
msgQ.Formatter = new System.Messaging.BinaryMessageFormatter();

// 收到的訊息轉為Hashtable格式
strHashtable = ((System.Collections.Hashtable)msgQ.Receive().Body);

// Get Type
ContextString = (string)strHashtable[(double)0];

// 如果收到的訊息為"Dispose” 代表傳訊的人要結束接收訊息的動作.那在下一次迴圈Sleep時
// 會執行傳訊的人所下的ThreadAll[0].Interrupt() 指令

if (ContextString == null || !ContextString.Equals("Dispose"))
{
this.setValueTable(strHashtable);
}
}
catch (System.Threading.ThreadInterruptedException e)
{
System.Console.WriteLine("Exception e:"+e.Message);
msgQ.Dispose();
break;
}
}
}


private System.Threading.Thread[] ThreadAll = new System.Threading.Thread[2];
private void StartListenMQThreads()
{
ThreadAll[0] = new System.Threading.Thread(new System.Threading.ThreadStart(ListenMDSQueue));
ThreadAll[0].Start();
}

// 這個例子有二個Thread , Main Thread 和 Linten Message Queue Thread
// 當Message Queeu Thread想改變Main Thread的資料時,要使用delegate的方式來達到目的

private delegate void InvokeUpdateState_forHashtable(System.Collections.Hashtable strHashtable);
private void setValueTable(System.Collections.Hashtable strHashtable)
{
if (this.InvokeRequired)
{
this.Invoke(new InvokeUpdateState_forHashtable(this.setValueTable), new object[] { strHashtable });
}
else
{
this.strHashtable_value = strHashtable;
}
}

沒有留言:

張貼留言