我有一个 WCF 服务,它执行搜索并向客户端返回一个相当复杂的对象列表。这是一个 EAV 系统,因此返回的每个实体都有一个附加值列表,其大小因实体蓝图而异。
在我的测试搜索中,我已通过日志确认几乎在所有情况下实际搜索都需要不到一秒的时间才能完成。在将响应返回给客户端之前,我做的最后一件事是记录处理已完成。
不幸的是,客户端直到我完成处理后 15-20 秒才收到响应。总响应大小约为 250kb,非常小。这一刻正在通过 LAN 传输,我已尝试禁用防火墙和防病毒软件以确保两者都没有干扰。
但是,我注意到,如果响应相当小,例如通过删除附加到每个实体的字段,则响应速度会快得多。我还尝试单步执行服务的本地托管 (IIS) 副本,在通过最后的 return
语句后,它仍然需要 15 秒才能到达本地客户端应用程序。
我正在使用 basicHttpBinding,因为该服务将由 .Net 和 PHP 客户端使用。
那么,谁能提出一种方法来确认确实是这种情况?我该如何解决极其缓慢的序列化时间问题?
编辑:
为了澄清,我用 [DataContract] 属性标记了每个类,用 [DataMember] 标记了每个属性 - 当我返回数据时,WCF 正在处理序列化。在这种情况下,它是一个实体类型的列表(一个包含值列表的自定义类。
编辑 2:
我测试了 DataContractSerializer 的速度,将包含 65 个返回实体的列表写入一个简单的内存流大约需要 15 秒。这看起来很荒谬,我不确定是什么改变让它变得如此缓慢。
最佳答案
想通了,还挺囧的。
在测试 DataContractSerializer 的速度时,我使用了从我的搜索中返回的 65 种产品的列表。我决定将所有产品(大约 600 个)加载到数据库中,然后将它们序列化到内存中,但出现了一些内存不足的异常,因此开始将结果写入文本文件。
原来文本文件有 1.5GB,大约是整个数据库大小的 3 倍。连载耗时17秒。所以实际上,它做得很好。发生的事情是每个产品都可以有一个附加实体的列表,并且这些也被加载了。因为它们是序列化的,所以这些实体是重复的,它们在数据库中只存在一次。
除了删除客户不需要的大量元数据外,我还设法将包含 50 种产品的列表(原为 194MB)缩小到仅 3MB。 (更新:这个周末我将 1.5GB 的列表降到了 66MB)。
故事的寓意?倾听社区的声音。其他人都告诉我 DataContractSerializer 有多快,所以当我觉得它很慢时,我应该责怪自己而不是 DataContractSerializer。
更新:
我花了一些时间试图弄清楚为什么这是一个突然的问题。答案在于 EAV 系统的性质——附加到任何实体的数据列表是动态的。我最初只是在请求单个实体时才加载字段数据——多个实体为了速度只加载了最低限度的数据。在我实现缓存后,我将其更改为无论如何加载所有字段数据,但由于复杂的数据模型和大量实体,我没有预料到这会对数据量产生多大的影响。真的,我不应该对我请求的数据量做出任何假设。
关于c# - 使用 DataContractSerializer 缓慢序列化 WCF 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18658408/