因为项目的需要,做了个OPC Client端,用其实现从OPC Server上实时取数,并将取出来的数提供给WebService,由于需要很快的刷新频率,不能把取出的数据写入到关系数据库,于是想到用一种内存共享的机制,找来找去,觉得用消息队列就可以满足要求了(也没有找到其他在C#下实现内存共享的方式,汗啊)。
废话不表,要用消息队列,首先要求机器上要安装消息队列......
另一要注意的问题,非域内机器,只能用私有队列,这就意味着WebService要和OPC Client端在同一台机器上
代理片段:
using System.Messaging;
protected string mqPath = @".private$MQSendOPCValueTableForDisplay";//私有消息队列名称
void mySubscription_DataChanged(object subscriptionHandle, object requestHandle, ItemValueResult[] values)

...{
DataTable myTagInfo = new DataTable();
myTagInfo.TableName = "OPCValueInfo";
myTagInfo.Columns.Add("TagName", typeof(string));
myTagInfo.Columns.Add("TagValue", typeof(string));
myTagInfo.Columns.Add("TagQuality", typeof(string));
if (InvokeRequired)

...{
//保证过程运行,其它控件响应事件也不能影响。

BeginInvoke(new DataChangedEventHandler(mySubscription_DataChanged), new object[] ...{ subscriptionHandle, requestHandle, values });//系统调用。
return;
}
try

...{
DataRow myRow;
foreach (ItemValueResult item in values)

...{
myRow = myTagInfo.NewRow();
myRow["TagName"] = item.ItemName.ToString();
myRow["TagValue"] = item.Value.ToString();
myRow["TagQuality"] = item.Quality.ToString();
myTagInfo.Rows.Add(myRow);
}
}
catch

...{

}

if (!MessageQueue.Exists(mqPath))

...{
MessageQueue.Create(mqPath);
}
MessageQueue mq = new MessageQueue(mqPath);
mq.Purge();//发送之前清空消息队列,保持消息队列中始终是最新的
mq.Send(myTagInfo);
}
好了,消息队列发送完毕。
下面是接收:
protected string mqPath = @".private$MQSendOPCValueTableForDisplay";
.
.
. [WebMethod]
public String[] GetTagValueInfo()

...{
DataTable TagInfo = new DataTable();
TagInfo.TableName = "TagInfo";
MessageQueue mq = new MessageQueue(mqPath);

mq.Formatter = new XmlMessageFormatter(new Type[] ...{ typeof(DataTable) });
string[] result = null;

try

...{
TimeSpan mySpan = new TimeSpan(0, 0, 20);
System.Messaging.Message m = mq.Receive(mySpan);
TagInfo = (DataTable)m.Body;
result = new string[TagInfo.Rows.Count];
for (int i = 0; i < TagInfo.Rows.Count; i++)

...{
result[i] = TagInfo.Rows[i][1].ToString();
}
}
catch

...{

}
return result;
}