表示为 XLANGMessage 的消息
XLANGMessage 对象表示使用 XLANG 服务声明的消息实例。 通过在方法调用中将对某一消息的引用作为参数传递,获取此对象。 XLANGPart 对象表示包含在 XLANG 服务内的消息实例中的消息部分。 此对象是通过在接收参数类型为 XLANGPart 的方法调用中传递部件引用或通过枚举 XLANGMessage 的传递引用来获取的。
业务流程消息变量可以传递给用户组件,并作为 XLANGMessage 对象接收。 XLANGMessage 对象允许访问部件和访问消息属性。用户可以“保留”XLANGMessage,从而将其生存期延长到声明范围之外。 随后,可能会从方法返回 XLANGMessage ,并将其分配给业务流程中的消息变量。
构造 XLANGMessage
使用流构造 XLANGMessage 时,流类型必须实现 IStreamFactory 或 为 MemoryStream。 以下代码示例演示如何构造 XLANGMessage:
public class FileStreamFactory : IStreamFactory
{
string _fname;
public FileStreamFactory(string fname)
{
_fname = fname;
}
public Stream CreateStream()
{
return new FileStream
(
_fname,
FileMode.Open,
FileAccess.Read,
FileShare.Read
);
}
}
public static void AssignStreamFactoryToPart(XLANGMessage msg)
{
IStreamFactory sf = new FileStreamFactory( @”c:\data.xml” );
msg[0].LoadFrom( sf );
}
可能有时候,您想要创建新的消息而不转换源消息。 可以使用System.Xml 类型的变量来执行此操作 。XmlDocument 和加载或以其他方式构造适当的内容。 在以下示例中,使用 XmlDocument 的 LoadXml 方法从字符串加载 XML:
XmlVariable.LoadXml("<ns0:Root PONumber="047745351122111" xmlns:ns0="http://BTSHTTPSend.SimpleSchema"><MyChildRecord SubAttr1="Simple Attribute " /></ns0:Root>");
XLANGMessage XmlMsg = XmlVariable;
以下示例使用 XmlDocument 的 Load 方法从文件加载 XML:
XmlVariable.Load("C:\MyData.xml");
XLANGMessage XmlMsg = XmlVariable;
注意
如果要构造更大的消息,请使用上一部分中演示的流式处理方法之一,或者考虑使用业务流程Designer中的转换形状。
使用 XLANGMessage 和 XLANGPart 时的注意事项
在用户代码中使用 XLANGMessage 和 XLANGPart 时,请考虑以下事项:
不要将消息部分作为 XLANGPart 参数传递或返回 XLANGPart 类型的值。 应将 XLANGPart 作为部件的类型传递。 例如:
Message String msg; Class.Test(msg); // or you can do the following Messagetype mt { String part; }; Message mt msg; Class.Test(msg,part);
还可以将消息本身作为 XLANGMessage 传递,并使用 XLANGMessage 下标运算符访问函数调用中的部分。 但是,不应将 XLANGPart 置于其生存期超过函数调用生存期的集合中。 相反,应将 XLANGMessage 放入集合中。 例如:
void Test(XLANGMessage xlm) { try { XLANGPart xlp = xlm[0]; string sval = (string)xlp.RetrieveAs(typeof(string)); } finally { xlm.Dispose(); } }
请勿将业务流程参数定义为 XLANGMessage 或 XLANGPart。 如果您想要传递某一消息,则使用某一消息类型参数来传递该消息。 如果您想要传递某一部分,则改为传递该消息,然后使用该部分。 如果您只是想要部分值,则使用部分类型传递该部分。
不要为方法调用返回 XLANGMessage 参数。 如果返回传入的 XLANGMessage 参数,然后无法在方法调用内的参数上调用 Dispose 方法,则它会直观地违反生存期假设,并且还会引发异常。 通过 XLANGMessage 参数将消息传递给用户代码时,将消息引用到通常没有消息引用的特殊上下文。 此上下文的生存期就是业务流程实例的生存期。 其原因在于,BizTalk Server 不知道用户代码是否将占有消息。
在业务流程实例退出时,在该实例中创建的任何消息都不再有效,因此,此类集合的生存期应短于或等于实例的生存期。 但是,如果要在通过与业务流程实例具有相同生存期的 XLANGMessage 参数传递消息时在循环中释放消息引用,则可以调用 XLANGMessage.Dispose 来释放引用。 此外,如果在用户代码方法中, XLANGMessage 参数仅在本地使用,并且参数的生存期包含在函数调用的生存期中,则还可以调用 XLANGMessage.Dispose 以释放对根上下文的引用,并返回相应的消息正常生存期行为。 例如:
void Test(XLANGMessage xlm) { try { //XLANGMessage is only used locally } finally { xlm.Dispose(); } }
如果将 xlm 放在集合中,则类本身必须具有用于清理的 Dispose 方法。 例如:
public class A { Hashtable h = new Hashtable(); public void Test(XLANGMessage xlm) { h[xlm] = 1; } //You can have more methods here public void Dispose() { foreach (XLANGMessage xlm in h.Keys) { xlm.Dispose(); } } }
完成 XLANGMessages 集合后,将调用 A.Dispose。