提高 DataSet 序列化和远程处理性能
在进程之间传递 System.Data.DataSet 对象时,将使用 .NET Framework Remoting 序列化、传输以及反序列化 DataSet 类。如果从 .NET Web 服务传回 DataSet 类,会在内部使用 Microsoft .NET Framework System.Xml.Serialization.XMLSerializer 类将 DataSet 数据序列化回客户端。如果从 COM+ 中承载的托管对象传回 DataSet,则 .NET Framework Remoting 使用 BinaryFormatter 类。无论 .NET Framework 使用何种远程处理机制,DataSet 类在序列化数据时始终将内部数据转换为 XML。
通过 .NET Framework Remoting 序列化 DataSet 中的少量数据(数百行)时,Microsoft .NET Framework 1.0 与 .NET Framework 1.1 中包含的 DataSet 类可以高效地工作。在处理较大的 DataSet(数千行)时,此序列化机制的效率不够高,并会导致较大的暂时(短期)内存分配。这些内存分配会降低应用程序的可伸缩性。
注意:暂时内存分配是在处理某些代码段过程中发生的短期内存分配。因此,在 DataSet 类的序列化、远程处理及反序列化期间,.NET Framework Remoting 会在内部分配和释放各种不同的托管对象,从而处理远程处理请求。分配和释放较大的托管对象会给 .NET 内存管理系统造成额外的压力,还会降低整体可伸缩性。例如,有多个未决方法调用(这些调用会产生较大的暂时内存分配)的应用程序可以在完成所有方法调用之前用尽内存。
通过使用正确设计的代理类型或序列化包装类,可以显著提高较大的 DataSet 的序列化和远程处理性能。
本文包含一个示例序列化包装类,该包装类经过优化以便更加高效地序列化和反序列化较大的 DataSet。相对于远程处理典型的 DataSet,该类显著减少了暂时内存分配。暂时内存分配的大幅度减少还缩短了使用较大 DataSet 时远程处理端到端时间,同时增强了可伸缩性。
该示例提供了一个名为 DataSetSurrogate 的序列化包装类。DataSetSurrogate 类用作您要进行远程处理的任何 DataSet 的包装类。服务器组件将所需的 DataSet 传递到 DataSetSurrogate 构造函数,然后将 DataSetSurrogate 类传回客户端。在客户端,将使用 DataSetSurrogate.ConvertToDataSet 方法从 DataSetSurrogate 类中提取 DataSet。
DataSetSurrogate 类标记为可序列化,并且 DataSetSurrogate 类中的所有字段同样也是可序列化类。因此,在远程处理 DataSetSurrogate 对象时,远程处理基础结构将自动序列化和反序列化 DataSetSurrogate 对象及其所有字段。与 DataSet 类相比,DataSetSurrogate 类的主要序列化优势在于,DataSetSurrogate 类以二进制格式序列化数据。无论在内存还是 CPU 方面,用二进制格式进行序列化的效率都比现有 DataSet XML 序列化格式高出许多。
注意:要使此序列化包装类的性能优势最大化,进行远程处理时请使用 .NET Framework System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 类。使用 .NET Framework System.Runtime.Serialization.Formatters.Soap.SoapFormatter 类进行远程处理不如使用 DataSetSurrogate 类效率高。
可以从 Microsoft 下载中心下载以下文件:
立即下载 SurrogateSample.exe 程序包。 (http://download.microsoft.com/download/2/8/2/28275f15-5a26-41aa-9bd8-80972c699d17/surrogatesample.exe)
通过 .NET Framework Remoting 序列化 DataSet 中的少量数据(数百行)时,Microsoft .NET Framework 1.0 与 .NET Framework 1.1 中包含的 DataSet 类可以高效地工作。在处理较大的 DataSet(数千行)时,此序列化机制的效率不够高,并会导致较大的暂时(短期)内存分配。这些内存分配会降低应用程序的可伸缩性。
注意:暂时内存分配是在处理某些代码段过程中发生的短期内存分配。因此,在 DataSet 类的序列化、远程处理及反序列化期间,.NET Framework Remoting 会在内部分配和释放各种不同的托管对象,从而处理远程处理请求。分配和释放较大的托管对象会给 .NET 内存管理系统造成额外的压力,还会降低整体可伸缩性。例如,有多个未决方法调用(这些调用会产生较大的暂时内存分配)的应用程序可以在完成所有方法调用之前用尽内存。
通过使用正确设计的代理类型或序列化包装类,可以显著提高较大的 DataSet 的序列化和远程处理性能。
本文包含一个示例序列化包装类,该包装类经过优化以便更加高效地序列化和反序列化较大的 DataSet。相对于远程处理典型的 DataSet,该类显著减少了暂时内存分配。暂时内存分配的大幅度减少还缩短了使用较大 DataSet 时远程处理端到端时间,同时增强了可伸缩性。
该示例提供了一个名为 DataSetSurrogate 的序列化包装类。DataSetSurrogate 类用作您要进行远程处理的任何 DataSet 的包装类。服务器组件将所需的 DataSet 传递到 DataSetSurrogate 构造函数,然后将 DataSetSurrogate 类传回客户端。在客户端,将使用 DataSetSurrogate.ConvertToDataSet 方法从 DataSetSurrogate 类中提取 DataSet。
DataSetSurrogate 类标记为可序列化,并且 DataSetSurrogate 类中的所有字段同样也是可序列化类。因此,在远程处理 DataSetSurrogate 对象时,远程处理基础结构将自动序列化和反序列化 DataSetSurrogate 对象及其所有字段。与 DataSet 类相比,DataSetSurrogate 类的主要序列化优势在于,DataSetSurrogate 类以二进制格式序列化数据。无论在内存还是 CPU 方面,用二进制格式进行序列化的效率都比现有 DataSet XML 序列化格式高出许多。
注意:要使此序列化包装类的性能优势最大化,进行远程处理时请使用 .NET Framework System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 类。使用 .NET Framework System.Runtime.Serialization.Formatters.Soap.SoapFormatter 类进行远程处理不如使用 DataSetSurrogate 类效率高。
可以从 Microsoft 下载中心下载以下文件: