【问题标题】:Returning big byte arrays from WCF - Memory issue从 WCF 返回大字节数组 - 内存问题
【发布时间】:2012-11-08 17:26:59
【问题描述】:

我需要从 WCF 服务器返回一个大字节数组。

问题是 - 为了返回这样一个数组 - 我需要创建一个 - 当创建这样一个数组时 - 它会自动进入大对象堆 - 这意味着当服务受到压力时 - 我得到一个内存使用和管理方面的真正问题。

我曾考虑使用非托管内存来避免使用大型托管字节数组 - 但仍然 - 如何从 WCF 服务返回这样的数组?

是否有任何方法可以从不包括实际创建托管字节数组的 WCF 服务返回字节“流”?我知道 WCF 本身使用 BufferManager - 所以如果它只是读取我的非托管内存并在发送之前使用它的缓冲区管理来存储它 - 我希望不会有问题。

【问题讨论】:

  • 能否尝试将其写入文件并让客户端下载该文件?
  • 是的,您可以返回Stream。你为什么不试试呢。
  • ryadavilli - 我担心从文件中写入和读取 1. 在某些情况下不安全(当数据敏感时)和 2. 需要 IO,这在性能方面很糟糕跨度>
  • L.B - 返回 UnmanagedMemoryStream 是不可能的 - 为了返回 MemoryStream - 它必须由字节数组支持...
  • @RoyReznik FileStream 也是流 :) 您还可以实现自己的流,它不会一次将所有数据加载到内存中。

标签: c# .net wcf memory large-object-heap


【解决方案1】:

您可以使用 WCF 的 Streaming Mode。从该页面:

  1. 要流式传输数据,服务的 OperationContract 必须满足两个要求:

    一个。保存要流式传输的数据的参数必须是唯一的 方法中的参数。例如,如果输入消息是 要进行流式传输,操作必须只有一个输入参数。 同样,如果要流式传输输出消息,则操作必须 要么只有一个输出参数,要么有一个返回值。

    b.参数和返回值的至少一种类型必须是 StreamMessageIXmlSerializable

  2. 必须在绑定上启用流式传输。您设置一个 TransferMode 属性,该属性可以采用以下值之一:

    一个。缓冲,

    b.流式传输,可实现双向流式通信。

    c。 StreamedRequest,仅启用流式传输请求。

    d。 StreamedResponse,仅启用流式传输响应。

该页面上也有一些不错的示例,包括如何写回自定义流(位于底部)。

有关编码、流式传输和会话的更多背景信息,以及使用流式传输时的一些安全注意事项,请参阅this MSDN page

【讨论】:

  • 听起来很有希望 - 我会去看看。
  • 不幸的是,在检查了限制之后 - 我的方法还返回了 2 个额外的输出参数(这是必须的.​​.....) - 有什么方法可以绕过它?
  • 您可以尝试使用 OperationContext.OutgoingMessageHeaders 属性在消息头中传递参数。来自msdn.microsoft.com/en-us/library/…:“使用此属性添加由服务操作发送的回复标头或由 WCF 客户端对象发送的请求标头。” stackoverflow.com/questions/964433/… 有一些很好的例子
  • 找到了一个更简单的方法 - 只需创建一个具有 MessageContract 属性的类 - 所有参数(未流式传输的)都应具有 MessageHeader 属性,流式参数应具有 MessageBodyMember 属性
猜你喜欢
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
相关资源
最近更新 更多