【问题标题】:Stream as a return value in WCF - who disposes it?流作为 WCF 中的返回值 - 谁处理它?
【发布时间】:2011-09-22 22:09:00
【问题描述】:

假设我有以下 WCF 实现:

public Stream Download(string path)
{
    FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
    return stream;
}

谁负责处理返回的值?毕竟,可能会发生网络故障,因此消费者可能无法处理它。

【问题讨论】:

  • @Magnus,如上所述,消费者可能无法处理它,因为可能存在网络故障。
  • @Magnus,hmmmmm,猜测很好,但我想有一个确定的答案:-)
  • 让消费者处理返回流与服务器端的对象引用无关,因为客户端正在获取对象的序列化版本,并且永远不会有对象引用指向它的位置服务器。

标签: .net wcf stream idisposable


【解决方案1】:

服务负责关闭流,除非您更改默认行为it does it automatically(始终使用默认值的行为)。如果您将OperationBehavior.AutoDisposeParameters 设置为false,则必须为OperationContext.OperationCompleted 注册处理程序并按照here 的描述在处理程序中处理流。

客户端无法关闭流,因为客户端有不同的流 - 您没有传递对流的引用或对文件处理程序的引用。内部文件内容被复制到传输和客户端在它自己的流实例中处理它(他负责处理它)。

【讨论】:

  • 很好的解释,但如果您在响应消息合同中遇到未处理的流,请考虑@peter-sladek 的回答,以我自己的经验,我可以保证
【解决方案2】:

如果您将 Stream 包装在 MessageContract 中(以便您可以在标头中发送更多信息),请注意 Stream 不会自动处理!正如属性 OperationBehavior.AutoDisposeParameters 的名称所暗示的那样,WCF 会自动处理输入/输出参数,因此您必须在 MessageContract 类上实现 IDisposable 并在那里关闭流。

【讨论】:

  • 那么你是说如果我的 Response 类中有一个 Stream 作为属性,那么响应类需要实现 IDisposable 并在那里处理流?换句话说,WCF 会确保 Response 被释放,而我的职责是确保 Dispose 的 Response 类代理到流属性?
  • 如果使用消息合约,是的。至少根据我在 2011 年的测试。你绝对应该做一些测试来验证它是否仍然需要。
  • 然后避免通常用于一些细粒度控制的消息合同。大多数业务应用程序不需要消息合约。
【解决方案3】:

您可以像下面这样在 WCF 中处理返回的流

FileStream stream=null;
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += (sender, args) =>
{
    if (stream != null)
        stream.Dispose();
};

stream = new FileStream(path, FileMode.Open, FileAccess.Read);
return stream;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 2016-02-12
    相关资源
    最近更新 更多